[Q&A] 啥是递归?
递归就是在运行的过程中调用自己
[Q&A]构成递归需具备的条件:
1,子问题须与原始问题为同样
的事
[Q&A] 递归套路
1、满足条件就终止
2、符合条件则调用递归方法
# 技巧:内容放在递归前和递归后 可以控制输出顺序
# 技巧:内容放在递归上和递归下 可以控制输出顺序
# 技巧:内容放在递归参数前和参数后 可以控制输出顺序
初始值型递归(满足条件就终止)
斐波那契数列
# 数组a的前三位已经赋值:a[0]=1,a[1]=2,a[2]=4,当i>=3时,数组元素a[i]=a[i-1]+a[i-2]+a[i-3]。
# 例如:1,2,4,7,13
/**
* 递归获取位置
*/
public static int fun(int loc) {
if (loc == 0) {
return 1;
} else if (loc == 1) {
return 2;
} else if (loc == 2) {
return 4;
}
return fun(loc - 1) + fun(loc - 2) + fun(loc - 3);
}
[简单] NC68.跳台阶
public int jumpFloor(int target) {
if (target == 1) {
return 1;
} else if (target == 2) {
return 2;
}
return jumpFloor(target - 1) + jumpFloor(target - 2);
}
10进制转2进制
/**
* 通常十进制转其他进制使用辗转相除法来求解,取余数的倒叙作为结果
* 如:例如302
* 302/2 = 151 余0
* 151/2 = 75 余1
* 75/2 = 37 余1
* 37/2 = 18 余1
* 18/2 = 9 余0
* 9/2 = 4 余1
* 4/2 = 2 余0
* 2/2 = 1 余0
* 1/2 = 0 余1
* 故二进制为100101110
*/
public static String fun(int num) {
if (num == 0) { // 商为0停止
return "";
}
int remainder = num % 2;
return fun(num / 2) + remainder;
}
String s = fun(302); // 100101110
---------------------------------------------------------------------------------------------
# 技巧:内容放在递归前和递归后 可以控制输出顺序
public static String fun(int num) {
if (num == 0) { // 商为0停止
return "";
}
int remainder = num % 2;
return remainder + fun(num / 2);
}
String s = fun(302); // 011101001
字符串填充0到指定长度
# 二进制不够32位前面填充0
private static String proFillZero(String str) {
if (str.length() >= 32) {
return str;
}
return proFillZero("0" + str);
}
System.out.println(proFillZero("10010"));
System.out.println(proFillZero("0010010"));
System.out.println(proFillZero("100110010"));
System.out.println(proFillZero("100010010110010"));
00000000000000000000000000010010
00000000000000000000000000010010
00000000000000000000000100110010
00000000000000000100010010110010
------------------------------------------------------------------------------------
# 长度不够8位整数后面填充0
# 技巧:内容放在递归参数前和参数后 可以控制输出顺序
public static String postFillZero(String str) {
if (str.length() >= 8) {
return str;
}
return postFillZero(str + "0");
}
System.out.println(postFillZero("1"));
System.out.println(postFillZero("11"));
System.out.println(postFillZero("111"));
System.out.println(postFillZero("1111"));
System.out.println(postFillZero("11111111"));
System.out.println(postFillZero("111111111"));
10000000
11000000
11100000
11110000
11111111
111111111
[中等] HJ20.密码验证合格程序
------------------------------------------------
字符串是否含有长度大于2的相同子串
-----------------------------------------------
/**
* 是否有长度为2的相同子串 (注:其他符号不含空格或换行)
*/
private static boolean hasSameSubStr(String str, int left, int right) {
// right为母串第一个字符位置,其必须范围有效
if (right >= str.length()) {
return false;
}
// 子串
String sonStr = str.substring(left, right);
// 母串
String motherStr = str.substring(right);
if (motherStr.contains(sonStr)) { // 母串是否包含子串
return true;
}
return hasSameSubStr(str, left + 1, right + 1);
}
System.out.println(hasSameSubStr("abcdefg",0,2)); // false
System.out.println(hasSameSubStr("abbcdefgabb",0,2)); // true
System.out.println(hasSameSubStr("abcdefabg",0,2)); // true
计算一系列数字的最大公约数(gcd)
public static OptionalInt gcd(int[] numbers) {
return Arrays.stream(numbers).reduce((a, b) -> gcd(a, b));
}
public static OptionalInt gcd(int[] numbers) {
return Arrays.stream(numbers).reduce((a, b) -> gcd(a, b));
}
private static int gcd(int a, int b) {
if (b == 0) {
return a;
}
return gcd(b, a % b);
}
private static int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
[简单] leetcode 144. 二叉树的前序遍历
[简单] leetcode 194. 二叉树的中序遍历
[简单] leetcode 145. 二叉树的后序遍历
/**
* 前序递归法
*/
public static void preOrderRecursion(BinTreeNode<Character> root, List<Character> res) {
// 终止条件
if (root == null) {
return;
}
// Consumer
res.add(root.data);
preOrderRecursion(root.lchild, res);
preOrderRecursion(root.rchild, res);
}
/**
* 中序递归法
*/
public static void inOrderRecursion(BinTreeNode<Character> root, List<Character> res) {
if (root == null) {
return;
}
inOrderRecursion(root.lchild, res);
res.add(root.data);
inOrderRecursion(root.rchild, res);
}
/**
* 后序递归法
*/
public static void postOrderRecursion(BinTreeNode<Character> root, List<Character> res) {
if (root == null) {
return;
}
postOrderRecursion(root.lchild, res);
postOrderRecursion(root.rchild, res);
res.add(root.data);
}
消费型递归(满足条件就递归处理)
进制转换算法
public static void fun(int num) {
int goInside = num / 2;
if (goInside >= 1) { // 商>=1说明num>=2
fun(goInside);
}
int remainder = num % 2;
System.out.print(remainder);
}
public static void fun1(Deque<Integer> res, int num) {
int goInside = num / 2;
if (goInside >= 1) {
fun1(res, goInside);
}
int remainder = num % 2;
res.addLast(remainder);
}
Deque<Integer> res = new LinkedList();
fun1(res, 500);
String collect = res.stream().map(String::valueOf).collect(Collectors.joining("")); // 111110100
fun(500); → 111110100 // 500的二进制
---------------------------------------------------------------------------------------------
# 技巧:内容放在递归上和递归下 可以控制输出顺序
public static void fun1(int num) {
int remainder = num % 2;
System.out.print(remainder);
int goInside = num / 2;
if (goInside >= 1) {
fun1(goInside);
}
}
public static void fun1(Deque<Integer> res, int num) {
int remainder = num % 2;
res.addLast(remainder);
int goInside = num / 2;
if (goInside >= 1) {
fun1(res, goInside);
}
}
fun1(500); → 001011111