刷《剑指Offer》有感Day04

回溯法

? 通常在二维矩阵上找路径这类问题都可以应用回溯法解决。

动态规划

如果面试题是求一个问题的最优解(通常是求最大值或者最小值),而且该问题能够分解成若干个子问题,并且子问题之间哈游重叠的更小子问题,就可以考虑用动态规划来解决这个问题。动态规划的四个特点:
? 求一个问题的最优解
? 整体问题的最优解是依赖各个子问题的最优解
? 把大问题分解成若干个小问题,这些小问题之间还有相互重叠的更小问题
? 从上往下分析问题,从下往上求解问题。由于子问题在分解大问题的过程中重复出现,为了避免重复求解子问题,我们可以用从下往上的顺序先计算小问题的最优解并存储下来,再以此为基础求
取大问题的最优解。

剪绳子

package Chapter2;

public class CutString {
	//动态规划
	public int maxProductAfterCutting_solution1(int length) {
		if(length < 2)
			return 0;
		if(length == 2)
			return 1;
		if(length == 3)
			return 2;
		
		int[] products = new int[length+1];
		products[0] = 0;
		products[1] = 1;
		products[2] = 2;
		products[3] = 3;
		
		int max = 0;
		
		for(int i = 4; i<=length; i++){
			max = 0;
			for(int j = 1; j<=i/2; j++){
				int product = products[j] * products[i-j];
				if(product > max)
					max = product;
			}
			products[i] = max;
		}
		
		return products[length];
	}
	//贪婪法
	public int maxProductAfterCutting_solution2(int length) {
		if(length < 2)
			return 0;
		if(length == 2)
			return 1;
		if(length == 3)
			return 2;
		
		int timeOf3 = length/3;
		
		if(length - timeOf3*3 == 1)
			timeOf3 -= 1;
		
		int timeOf2 = (length-timeOf3*3)/2;
		
		return (int)Math.pow(3, timeOf3)*(int)Math.pow(2,timeOf2);
		
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		CutString cs = new CutString();
		int length = 41;
		System.out.println(cs.maxProductAfterCutting_solution1(length));
		System.out.println(cs.maxProductAfterCutting_solution2(length));
		

	}

}

位运算

二进制的位运算一共有五种:与、或、异或、左移和右移。
? 左移运算符m<<n表示把m左移n位。在左移n位的时候,最左边的n位将被丢弃,同时在最右边补上n个0。比如:
00001010<<2 = 00101000
10001010<<3 = 01010000
把数左移一位相当于乘以2,左移两位相当于乘以4,一次类推左移n位相当于将m乘以pow(2,n)。在实际编程中应尽可能的用移位运算代替乘除法。
? 右移运算符m>>n表示把m右移n位。在右移n位的时候,最右边的n位将被丢弃。但右移时处理最左边位的情形要稍微复杂一点。如果数字是一个无符号数值,则用0填补最左边的n位:如果数字是一个有符号数值,则用数字的符号位填补最左边的n位。也就是说,如果数字原先是要给正数,则右移之后在最左边补n个0;如果数字原先是负数,则右移之后在最左边补n个1。下面是对两个8位有符号数进行右移的例子:
00001010>>2 = 00000010
10001010>>3 = 11110001

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值