暴力递归

暴力递归

思想:

  • 暴力递归就是尝试
    • 把问题转化为规模缩小的同类问题的子问题
    • 有明确的不需要进行继续递归的条件
    • 有当得到了子问题结果之后的决策过程
    • 不记录每个子问题的解

记录每个问题的解是动态规划,不记录每个过程的解是暴力递归

汉诺塔

打印n层汉诺塔从最左边移动到最右边的全部过程
假设数字为3个

  • 项目
    • 1,2左->中间
      • 1左->右
      • 2左->中间
      • 1右->中间
    • 3左->右边
    • 1,2中间->右边
      • 1中间->左边
      • 2中间->右边
      • 1左边-右边

代码实现如下:

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));
	}
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
回答: 递归求解二维数组路径可以使用暴力递归的方式。思路是,对于二维数组中的每一个点,记录其到终点(右下角点)的最小路径和。具体做法是,分别查看该点的正下方和右边两个点的值,选择其中较小的一个与数组原位置的值相加。最终,数组左上角位置的值即为问题的解。\[1\] #### 引用[.reference_title] - *1* [二维数组从左上到右下,返回最小路径和问题的解法](https://blog.csdn.net/z1171127310/article/details/127716640)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [LeetCode题目总结——二维数组](https://blog.csdn.net/weixin_40131652/article/details/108680706)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [二维数组的最小路径和问题](https://blog.csdn.net/hotonyhui/article/details/126962888)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down28v1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值