暴力递归
思想:
- 暴力递归就是尝试
- 把问题转化为规模缩小的同类问题的子问题
- 有明确的不需要进行继续递归的条件
- 有当得到了子问题结果之后的决策过程
- 不记录每个子问题的解
记录每个问题的解是动态规划,不记录每个过程的解是暴力递归
汉诺塔
打印n层汉诺塔从最左边移动到最右边的全部过程
假设数字为3个
- 项目
- 1,2左->中间
- 1左->右
- 2左->中间
- 1右->中间
- 3左->右边
- 1,2中间->右边
- 1中间->左边
- 2中间->右边
- 1左边-右边
- 1,2左->中间
代码实现如下:
package Digui;
public class prim1 {
public static void hao(int n){
if (n>0) {
fun(n,"left","right","mid");
}
}
public static void fun(int N, String from,String to, String other){
if (N==1) {
System.out.println("move 1 from"+" "+from+" "+"to"+" "+to);
}
else {
fun(N-1, from, other, to);
System.out.println("move"+ N +"from"+" "+from+" "+"to"+" "+to);
fun(N-1, other, to, from);
}
}
public static void main(String[] args) {
int n=3;
hao(n);
}
}
/*move 1 from left to right
move2from left to mid
move 1 from right to mid
move3from left to right
move 1 from mid to left
move2from mid to right
move 1 from left to right*/
逆序栈
给你一个栈,请你逆序这个栈,不能申请额外的数据结构,只能使用递归函数
给123的栈,
把栈的元素去到底,并返回
代码如下:
package Digui;
import java.util.Stack;
public class ReverseStack {
public static void Reverse(Stack<Integer> stack){
if (stack.isEmpty()) {
return;
}
int i=fun(stack);
Reverse(stack);
stack.push(i);
}
public static int fun(Stack<Integer> stack){
int result=stack.pop();
if(stack.isEmpty()){
return result;
}else {
int last=fun(stack);
stack.push(result);
return last;
}
}
public static void main(String[] args) {
Stack<Integer> test=new Stack<>();
test.push(1);
test.push(2);
test.push(3);
test.push(4);
test.push(5);
test.push(6);
Reverse(test);
while(!test.isEmpty()){
System.out.print(test.pop()+" ");
}
}
}
并查集合并user
如果两个user,a字段一样,或者b字段一样,或者c字段一样,就认为是一个人,请合并user,返回合并之后的用户数量
package Digui;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Stack;
public class Mergeusers {
public static class Node<V> {
V value;
public Node(V v) {
value = v;
}
}
public static class UnionFind<V> {
public HashMap<V, Node<V>> nodes = new HashMap<>();
public HashMap<Node<V>, Node<V>> parents = new HashMap<>();
public HashMap<Node<V>, Integer> sizeMap = new HashMap<>();
public UnionFind(List<V> values){
for(V cur:values){
Node<V> node = new Node<>(cur);
nodes.put(cur, node);
parents.put(node, node);
sizeMap.put(node, 1);
}
}
// 给你一个节点,请你往上到不能再往上,把代表返回
public Node<V> findFather(Node<V> cur) {
Stack<Node<V>> path = new Stack<>();
while (cur != parents.get(cur)) {
path.push(cur);
cur = parents.get(cur);
}
while (!path.isEmpty()) {
parents.put(path.pop(), cur);
}
return cur;
}
public boolean isSameSet(V a, V b) {
return findFather(nodes.get(a)) == findFather(nodes.get(b));
}
public void union(V a, V b) {
Node<V> aHead = findFather(nodes.get(a));
Node<V> bHead = findFather(nodes.get(b));
if (aHead != bHead) {
int aSetSize = sizeMap.get(aHead);
int bSetSize = sizeMap.get(bHead);
Node<V> big = aSetSize >= bSetSize ? aHead : bHead;
Node<V> small = big == aHead ? bHead : aHead;
parents.put(small, big);
sizeMap.put(big, aSetSize + bSetSize);
sizeMap.remove(small);
}
}
public int sets() {
return sizeMap.size();
}
}
public static class User{
public String a;
public String b;
public String c;
public User(String a,String b,String c){
this.a=a;
this.b=b;
this.c=c;
}
@Override
public String toString(){
return "a:" + a + " b:" + b + " c:" + c;
}
}
public static int mergeuse(List<User> users){
UnionFind<User> userfind=new UnionFind<>(users);
HashMap<String, User> mapA=new HashMap<>();
HashMap<String, User> mapB=new HashMap<>();
HashMap<String, User> mapC=new HashMap<>();
for(User user:users){
if (mapA.containsKey(user.a)) {
userfind.union(user, mapA.get(user.a));
}
else{
mapA.put(user.a, user);
}
if (mapB.containsKey(user.b)) {
userfind.union(user, mapB.get(user.b));
}
else{
mapB.put(user.b, user);
}
if (mapC.containsKey(user.c)) {
userfind.union(user, mapC.get(user.c));
}
else{
mapC.put(user.c, user);
}
}
//向并差集询问还有多少user
return userfind.sets();
}
public static void main(String[] args) {
User user1=new User("1","10","13");
User user2=new User("2","10","37");
User user3=new User("100","200","37");
List<User> users=new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
for(User user:users){
System.out.println(user);
}
System.out.print(mergeuse(users));
}
}
打印字符串子序列
打印一个字符串的全部子序列
子序列:把一个位置的字符彻底地要或是不要
package Digui;
import java.util.List;
import java.util.ArrayList;
public class PrintAllSubsquences {
public static List<String> subs(String s){
char[] str=s.toCharArray();
String path=" ";
List<String> ans=new ArrayList<>();
process1(str, 0, ans, path);
return ans;
}
//str固定,不变
//index此时来到的位置,要或者不要
//如果index来到str的终止位置,将沿途路径所形成的答案放入ans中
//之前作出的选择就是path
public static void process1(char[] s,int index,List<String> ans,String path){
if (index==s.length) {
ans.add(path);
return;
}
String no=path;
process1(s, index+1, ans, no);
String yes=path+String.valueOf(s[index]);
process1(s, index+1, ans, yes);
}
public static void main(String[] args) {
String s="abcd";
System.out.println(subs(s));
}
}
//[ , d, c, cd, b, bd, bc, bcd, a, ad, ac, acd, ab, abd, abc, abcd]
打印字符串子序列(不重复)
打印一个字符串的全部子序列,要求不要出现重复字面值的子序列
package Digui;
import java.util.List;
import java.util.ArrayList;
import java.util.HashSet;
public class PrintAllSubsquences1 {
public static List<String> SubNoRepeat(String s){
char[] str=s.toCharArray();
String path=" ";
HashSet<String> ans=new HashSet<>();
process2(str, 0, ans, path);
List<String> ans1=new ArrayList<>();
for(String cur:ans){
ans1.add(cur);
}
return ans1;
}
//str固定,不变
//index此时来到的位置,要或者不要
//如果index来到str的终止位置,将沿途路径所形成的答案放入ans中
//之前作出的选择就是path
public static void process2(char[] s,int index,HashSet<String> ans,String path){
if (index==s.length) {
ans.add(path);
return;
}
String no=path;
process2(s, index+1, ans, no);
String yes=path+String.valueOf(s[index]);
process2(s, index+1, ans, yes);
}
public static void main(String[] args) {
String s="aaa";
System.out.println(SubNoRepeat(s));
}
}
//[ , aa, a, aaa]
打印字符串全部排列
打印一个字符串的全部排列
package Digui;
import java.util.ArrayList;
public class printallPermutation {
public static ArrayList<String> Permutation(String str){
ArrayList<String> res=new ArrayList<>();
if(str==null||str.length()==0){
return res;
}
char[] chs=str.toCharArray();
process(chs, 0, res);
return res;
}
//str[0...i]已经是做好决定的
//str[i...]都有机会来到i位置
//i终止位置,就是str当前样子,就是一种结果->ans
public static void process(char[] str,int i,ArrayList<String>ans ){
if (i==str.length) {
ans.add(String.valueOf(str));
}
for (int j = i; j < str.length; j++) {
swap(str,i,j);
process(str, i+1, ans);
swap(str,i,j);
}
}
public static void swap(char[] arr,int i,int j){
char temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public static void main(String[] args) {
String s="123";
System.out.println(Permutation(s));
}
}
//[123, 132, 213, 231, 321, 312]
打印字符串全部排列(不重复)
打印一个字符串的全部排列
package Digui;
import java.util.HashSet;
public class printallPermutationNorepeat {
public static HashSet<String> Permutation(String str){
HashSet<String> res=new HashSet<>();
if(str==null||str.length()==0){
return res;
}
char[] chs=str.toCharArray();
process(chs, 0, res);
return res;
}
//str[0...i]已经是做好决定的
//str[i...]都有机会来到i位置
//i终止位置,就是str当前样子,就是一种结果->ans
public static void process(char[] str,int i,HashSet<String>ans ){
if (i==str.length) {
ans.add(String.valueOf(str));
}
for (int j = i; j < str.length; j++) {
swap(str,i,j);
process(str, i+1, ans);
swap(str,i,j);
}
}
public static void swap(char[] arr,int i,int j){
char temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public static void main(String[] args) {
String s="1233";
System.out.println(Permutation(s));
//[1233, 1233, 1323, 1332, 1332, 1323, 2133, 2133, 2313, 2331, 2331, 2313, 3213,
//3231, 3123, 3132, 3312, 3321, 3231, 3213, 3321, 3312, 3132, 3123]
//不重复的结果
//[1323, 2313, 1233, 1332, 3213, 3312, 2133, 2331, 3123, 3321, 3231, 3132]
}
}
另外一种版本
package Digui;
import java.util.ArrayList;
public class printallPermutationNorepeat1 {
public static ArrayList<String> Permutation(String str){
ArrayList<String> res=new ArrayList<>();
if(str==null||str.length()==0){
return res;
}
char[] chs=str.toCharArray();
process(chs, 0, res);
return res;
}
//str[0...i]已经是做好决定的
//str[i...]都有机会来到i位置
//i终止位置,就是str当前样子,就是一种结果->ans
public static void process(char[] str,int i,ArrayList<String>ans ){
if (i==str.length) {
ans.add(String.valueOf(str));
}
boolean[] visit=new boolean[26];
for (int j = i; j < str.length; j++) {
if (!visit[str[j]-'a']) {
visit[str[j]-'a']=true;
swap(str,i,j);
process(str, i+1, ans);
swap(str,i,j);
}
}
}
public static void swap(char[] arr,int i,int j){
char temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public static void main(String[] args) {
String s="aaa";
System.out.println(Permutation(s));
}
}