缺少Jdk8的朋友点这里[Win+Mac+Linux]提取码:Rvsj
汉诺塔:汉诺塔:汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘斜体样式
- A柱全部移交至C,B相当于中间者的思维步骤分析
圆盘数 | 步骤经过 | 步数累计 |
---|---|---|
1 | A->C | 2^-1=1 |
2 | A->B;A->C;B->C | 2^2-1=3 |
3 | A->C;A->B;C->B;A->C;B->A;B->C;A->C | 2^3-1=7 |
… | … | … |
n | … | 2^n-1 |
/**
* 从pos1位置 挪到 pos2位置
*
* @param pos1
* @param pos2
*/
public static void move(char pos1, char pos2) {
System.out.println(pos1 + "->" + pos2 + " ");
}
/**
* @param n:盘子个数
* @param pos1:起始位置
* @param pos2:中途位置
* @param pos3:目的位置
* 1 A->C 2^1-1
* 2 A->B A->C B-C 2^2-1
* 3 A->C A->B C->B A->C B->A B->C A->C 2^3-1
*/
public static void hanoi(int n, char pos1, char pos2, char pos3) {
if (n == 1) {
move(pos1, pos3);
} else {
hanoi(n - 1, pos1, pos3, pos2);
move(pos1, pos3);
hanoi(n - 1, pos2, pos1, pos3);
}
测试结果与我们的推算符合
当求所需挪动步骤的简单方法
/*
利用数学公式简便计算
*/
public static void hanoi_2() {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
System.out.println(Math.pow(2, num) - 1);
}
青蛙跳台阶:一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级。求该青蛙跳上一个n 级的台阶总共有多少种跳法
分析:当只有n=1,1节台阶时候,只有1种跳法;n=2,两阶台阶,有两种跳法;n=3,三阶台阶的跳法就是1阶台阶跳法加上3-1阶台阶跳法因此只有3种;n=4时候3+2=5种…
public static int Jump_1(int target) {
if (target == 1) {
return 1;
} else if (target == 2) {
return 2;
} else {
return Jump_1(target - 1) + Jump_1(target - 2);
}
}
青蛙跳台阶变态版:一只青蛙一次可以跳上1级台阶,也可以跳上2 级……它也可以跳上n 级,此时该青蛙跳上一个n级的台阶总共有多少种跳法
分析:由上题分析思维可得n个台阶的步骤和就是0~n-1个的步骤总和即:f(n) = f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n)
数学函数拆解:
f(n)
= f(n-1) + f(n-2) + f(n-3) + … + f(n-(n-1)) + f(n-n)=f(0)+f(1)+f(2)+...f(n-1)
f(n-1)
= f(0) + f(1)+f(2)+f(3) + … + f((n-1)-1) =f(0) + f(1) + f(2) + f(3) + ... + f(n-2)
- f(n)-f(n-1)=f(n-1)
- f(n)=2*f(n-1)
- 步骤分析
台阶 | 步骤 |
---|---|
0 | 0 |
1 | 1 |
2 | 2 |
… | … |
n | 2*Fib(n-1) |
public static int Jump_2(int target) {
if (target<1) {
return 0;
}else if (target == 1){
return 1;
} else{
return 2*Jump_2(target-1);
}
}
初识数组
/**
* 数组是引用类型,在堆上,内存连续
* new:实例化一个对象,在堆上
* arr变量名存放数组地址[首元素地址],该地址指向堆区
* <p>
* Java虚拟机栈 Java本地方法栈
* 堆 方法区 程序计数器
* <p>
* 栈上的地址拿不到
* 堆上的地址可以打印但不真实;也可以当做真实的,地址是唯一的[hash]
*/
public static void Arr() {
int[] arr1 = {
1, 2, 3, 4};
int[] arr2 = new int[]{
11, 22, 33, 44};
int[] arr3 = new int[4];//0
int a = 10;//a在栈上
int[] arr3_1 = new int[a];
System.out.println(arr1);//打印的地址,不过是假的,但是唯一的假地址
int len = arr1.length;//属性
System.out.println(len);
for (int i = 0; i < arr1.length; i++) {
System.out.print(arr1[i] + " ");
}
System.out.println();
for (int val : arr1) {
System.out.print(val + " ");
}
System.out.println();
}
/**
* 数组进行参数传递
*
* @param arr
*/
public static void Print(int[] arr) {
for (int val : arr) {
System.out.print(val + " ");
}
}
public static String my_toString(int[] arr) {
String ret = "[";
for (int i = 0; i < arr.length; i++) {
ret += arr[i];
if (i != arr.length - 1) {
ret += ", ";
}
}
ret += "]";
return ret;
}
public static void hanoi_2() {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
System.out.println(Math.pow(2, num) - 1);
}
数组总结
- 动态创建数组:
int[] arr = new int[100];
- 静态创建:
int[] arr = {1,2,3};
- int[] arr = null;//
arr引用的空类像,null不是0地址;C:int *p = NULL;//NULL代表0地址处
- 堆 和 方法区都是所有线程共享的
- Arrays.sort排序没有返回值 小->大:
Arrays.sort(arr);
Arrays.toString(arr);
利用Arrays.toString()方法可直接输出数组- 模拟实现Arrays.toString方法
public static String my_toString(int[] arr) {
String ret = "[";
for (int i = 0; i < arr.length; i++) {
ret += arr[i];
if (i != arr.length - 1) {
ret += ", ";
}
}
ret += "]";
return ret;
}