剑指Offer面试题(第二十八天)面试题46、47

* 面试题46:把数字翻译成字符串


     * 题目:给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成a,1翻译成b,。。。,25翻译成z
     * 一个数字可能有多种翻译。
     * 例如,12258有5种翻译,分别是bccfi,bwfi,bczi,mcfi,mzi
     * 请编程实现一个函数,用力啊计算一个数字有多少种不同的编译方法
     * 
     * 
     * 思路:动态规划的思路进行解题,自下而上解决子问题
     * 从数字的末尾开始,然后从右到左翻译并计算不同翻译的数目
     * f(r-2) = f(r-1) + g(r-2,r-1)*f(r)

https://www.jianshu.com/p/80e1841909b7

package Test;

public class No46GetTranslationCount {

	/*
	 * 面试题46:把数字翻译成字符串
	 * 题目:给定一个数字,我们按照如下规则把它翻译为字符串:0翻译成a,1翻译成b,。。。,25翻译成z
	 * 一个数字可能有多种翻译。
	 * 例如,12258有5种翻译,分别是bccfi,bwfi,bczi,mcfi,mzi
	 * 请编程实现一个函数,用力啊计算一个数字有多少种不同的编译方法
	 * 
	 * 
	 * 思路:动态规划的思路进行解题,自下而上解决子问题
	 * 从数字的末尾开始,然后从右到左翻译并计算不同翻译的数目
	 * f(r-2) = f(r-1) + g(r-2,r-1)*f(r)
	 * 
	 * 
	 * */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		System.out.println("-10翻译为字符串的数目为:"+getTranslationCount(-10));
		System.out.println("1234翻译为字符串的数目为:"+getTranslationCount(1234));
		System.out.println("12258翻译为字符串的数目为:"+getTranslationCount(12258));
	}

	private static int getTranslationCount(int number) {
		// TODO Auto-generated method stub
		if(number < 0)
			return 0;
		
		return getTranslationCount(Integer.toString(number));
	}

	//动态规划  从右到左计算子问题
	//f(r-2) = f(r-1)+g(r-2,r-1)*f(r)
	//其中若第r-2位数字和第r-1位数字在10-25范围内(也就是能够翻译为字符串),则g(r-2,r-1)=1;否则=0
	//其中f(r)表示从第r位到最右边所能翻译为字符串的数目
	private static int getTranslationCount(String number) {
		// TODO Auto-generated method stub
		int f1 = 0,f2 = 1,g = 0;
		int temp;
		for(int i = number.length()-2;i >= 0;i--) {
			if(Integer.parseInt(number.charAt(i)+""+number.charAt(i+1))<26)
				g = 1;
			else
				g = 0;
			temp = f2;
			f2 = f2 + g*f1;
			f1 = temp;

		}
		return f2;
	}

}

* 面试题47:礼物的最大价值


     * 题目:在一个m*n的棋盘的每一个都放有一个礼物,每个礼物都有一定的价值(价值大于0).
     * 可以从棋盘的左上角开始拿格子里的礼物,并每次向左或者向下移动一格,直到到达期盼的右下角。
     * 给定一个棋盘以及上面的礼物,请计算最多能拿到多少价值的礼物?
     * 
     * 思路:运用动态规划思想,f(i,j)=max{f(i-1,j),f(i,j-1)}+values(i,j)
     * f(i,j)表示到达(i,j)格子是能拿到的礼物总和的最大值
     * 用辅助的数组来保存中间计算结果
     *其中辅助数组不用和m*n的二维数组一样大,只需要保存上一层的最大值就可以了
     *使用长度为列数n的一维数组作为辅助数组
     * 
     * https://www.cnblogs.com/yongh/p/9950556.html
     * 其中注意:
     * 1>动态规划问题,使用公式表示其中的关系
     * 2>当动态规划中有大量重复计算,可以使用循环和辅助空间来提高效率
     * 3>若是遇到需要对中间结果进行保存的问题的时候,可能能否游湖辅助空间(二维数组----->一维数组空间)
 

package Test;

public class No47GetMaxValue {

	/*
	 * 面试题47:礼物的最大价值
	 * 题目:在一个m*n的棋盘的每一个都放有一个礼物,每个礼物都有一定的价值(价值大于0).
	 * 可以从棋盘的左上角开始拿格子里的礼物,并每次向左或者向下移动一格,直到到达期盼的右下角。
	 * 给定一个棋盘以及上面的礼物,请计算最多能拿到多少价值的礼物?
	 * 
	 * 思路:运用动态规划思想,f(i,j)=max{f(i-1,j),f(i,j-1)}+values(i,j)
	 * f(i,j)表示到达(i,j)格子是能拿到的礼物总和的最大值
	 * 用辅助的数组来保存中间计算结果
	 *其中辅助数组不用和m*n的二维数组一样大,只需要保存上一层的最大值就可以了
	 *使用长度为列数n的一维数组作为辅助数组
	 * 
	 * https://www.cnblogs.com/yongh/p/9950556.html
	 * 其中注意:
	 * 1>动态规划问题,使用公式表示其中的关系
	 * 2>当动态规划中有大量重复计算,可以使用循环和辅助空间来提高效率
	 * 3>若是遇到需要对中间结果进行保存的问题的时候,可能能否游湖辅助空间(二维数组----->一维数组空间)
	 * */
	public static void main(String[] args) {
		// TODO Auto-generated method stub

		int[][] values = {{1,10,3,8},{12,2,9,6},{5,7,4,11},{3,7,16,5}};
		No47GetMaxValue g = new No47GetMaxValue();
		System.out.println("最多能拿到"+g.GetMaxValue(values)+"价值的礼物!!!");
	}

	public int GetMaxValue(int[][] values) {
		// TODO Auto-generated method stub
		if(values == null || values.length <= 0 || values[0].length <= 0)
			return -1;
		int rows = values.length;
		int cols = values[0].length;
		
		int[] maxValue = new int[cols];
		for(int i = 0;i < rows;i++) {
			for(int j = 0;j < cols;j++) {
				int left = 0;
				int up = 0;
				if(i > 0)
					up = maxValue[j];
				if(j > 0)
					left = maxValue[j-1];
				
				maxValue[j] = Math.max(up, left)+values[i][j];
				
			}
			
		}
		return maxValue[cols-1];
	}

}

猜你喜欢

转载自blog.csdn.net/weixin_43137176/article/details/89500178