初级算法--暴力递归(待完善)

9.1 背包问题: 给定两个长度为n的数组weight和values,weight[i]和values[i]分别代表i号物品的重量和价值,给定一个载重为正数的袋子bag,最多能装的价值为多少

按理来说应该是没有问题的,但是代码跑出来是有问题的代码跑出来是有问题的

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        int[] weights = {3, 2, 4, 7};
        int[] values = {5, 6, 3, 19};
        int bag = 11;
        int k = process(weights,values,0,bag,0);
		
		
	}
	
	public static int process(int[] weights,int[] values,int i,int bag,int alreadyWeight) {
		
		if (alreadyWeight > bag) {
			return 0;
		}
		
		if (i == weights.length) {
			return 0;
		}
		
		int k = Math.max(process(weights,values,i+1,bag,alreadyWeight),
				values[i]+process(weights,values,i+1,bag,alreadyWeight+weights[i]));
		return k;
	}
}

以下形式是没有问题的

public class Main {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
        int[] weights = {3, 2, 4, 7};
        int[] values = {5, 6, 3, 19};
        int bag = 11;
        int k = process(weights,values,0,bag,0);
		
		
	}
	
	public static int process(int[] weights,int[] values,int i,int bag,int alreadyWeight) {
		
		if (i == weights.length) {
			return 0;
		}
		
		int no = process(weights,values,i+1,bag,alreadyWeight);
		
		/*   !!! 这里最关键  !!!  */
		/*   !!! 上面那样写是错误的写法 !!!  */
		if (alreadyWeight+weights[i] > bag) {
			return 0;
		}
		int yes = values[i]+process(weights,values,i+1,bag,alreadyWeight+weights[i]);
		
		return Math.max(no, yes);
	}
}

9.1 给定一个整型数组arr,代表数值不同的纸牌排成一条线。玩家A和玩家B依次拿走每张纸牌,规定玩家A先拿,玩家B后拿。但是每个玩家每次只能拿走最左或最右的纸牌,玩家A和玩家B都绝顶聪,请返回最后获胜者的分数。

其实这个要靠记住了,想想出来的可能性不大

public class CardsInLine {

	public static int win1(int[] arr) {
		
		if (arr == null || arr.length == 0) return 0;
		
		// 返回先手或者后手的最大值
		return Math.max(f(arr,0,arr.length-1), s(arr,0,arr.length-1));
	}
	
	// 先手
	public static int f(int[] arr,int L,int R) {
		
		if (L == R) return arr[L];
		
		return Math.max(arr[L]+s(arr,L+1,R),arr[R]+s(arr,L,R-1));
	}
	
	// 后手
	public static int s(int[] arr,int L,int R) {
		if (L == R) return 0;
		
		// 后手就是先手的最小值,范围确定好
		return Math.min(f(arr,L+1,R),f(arr,L,R-1));
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] arr = {1,2,100,4};
		System.out.println(win1(arr));
	}

}

9.3 给你一个栈,请你逆序这个栈,不能申请额外的数据结构,只能使用递归函数,如何实现

就是每一次递归都拿到栈底的值,直到栈为null后开始回调,将拿到的栈底的值依次插入栈中

public class ReverseStack {
	
	public static void reverse(Stack<Integer> stack) {
		
		if (stack.isEmpty()) return;
		
		int i = f(stack);
		reverse(stack);
		stack.push(i);	
	}
	
	// 拿到栈底的值
	public static int f(Stack<Integer> stack) {
		
		int result = stack.pop();
		
		if (stack.isEmpty()) {
			return result;
		} 
		else {
			int last = f(stack);
			stack.push(result);
			return last;
		}
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Stack<Integer> stack = new Stack<>();
		stack.add(1); stack.add(2); stack.add(3); stack.add(4); stack.add(5);
		
		reverse(stack);
		
		String s = stack.toString();
		System.out.println(s);

	}
}

9.4 规定1和A对应、2和B对应、3和C对应…,那么一个数字字符串比如“111”,就可以转换为“AAA”、“KA”和“AK”。给定一个只有数字字符组成的字符串str,返回有多少种转换结果。

假设从i位置开始,i位置之前的字符是转换好的,那么
如果i位置的字符为0的话那么就返回0,因为没有办法转换了,
如果i位置的字符为1的话,可以分为两种情况,自己转换,递归i+1,和加上后一个字符转换,递归i+2,
如果i位置的字符为2的话,可以像1一样去转换,但是后一个字符不能超过6,因为超过6就没办法转换了

public class TransformationStr {
	
	public static int process(char[] str,int i) {
		
		if (i == str.length) {
			return 1;
		}
		
		if (str[i] == '0') {
			return 0;
		}
		
		if (str[i] == '1') {
			int res = process(str,i+1);
			if (i+1 < str.length) {
				res += process(str,i+2);
			}
			return res;
		}
		
		if (str[i] == '2') {
			int res = process(str,i+1);
			
			if (i+1 < str.length && (str[i+1] >= '0' && str[i+1] <= '6') ) {
				res += process(str,i+2);
			}
			return res;
		}
		
		return process(str,i+1);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		String s = "7210231231232031203123";
		char[] str = s.toCharArray();
		System.out.println(process(str,0));

	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值