动态规划问题:47 礼物的最大价值; 48 最长不含重复字符的子字符串

本文总结《剑指offer》中使用动态规划思路高效率解决问题的几个典型题目:

1、面试题47 礼物的最大价值

思路:首先,最简单的思路是使用递归逐步计算,但这样存在大量重复计算,该方法舍弃!

其次,我们想到构造一个辅助二维数组,数组中座标为(i,j)的元素表示到达座标为(i,j)的格子时能拿到的礼物价值总和的最大值。仔细想一下,其实在二维数组中存储的很多元素是我们并不需要的。比如座标(i,j)处的值只取决于(i-1,j)和(i, j-1)两个位置的元素。所以我们可以继续简化为一维辅助数组,代码实现如下:

package offer.coder;

/**
 * 
 * @author FHY
 * 礼物的最大价值,动态规划实现  
 */
public class GetMaxValueDemo47_2 {

	public static void main(String[] args) {
		
		int[][] arr = {{1,10,3,8},{12,2,9,6},{5,7,4,11},{3,7,16,5}};
		
		System.out.println(getMaxValue(arr));
	}

	private static int getMaxValue(int[][] arr) {
		if(arr.length == 0 || arr[0].length == 0){
			return 0;
		}
		
		int rows = arr.length;
		int cols = arr[0].length;
		int[] maxArr = new int [cols];
		
		
		for(int i = 0; i < rows; i++){
			for(int j = 0; j < cols; j++){
				int left = 0;
				int up = 0;
				if(j > 0)
					up = maxArr[j - 1];
				if(i > 0)
					left = maxArr[j];
				maxArr[j] = max(up, left) + arr[i][j];
			}
		}
		return maxArr[cols - 1];
	}

	private static int max(int a, int b) {
		return a > b ? a : b;
	}
}

2、最长不含重复字符的子字符串

思路:该题我们已知字符串中的字母都是‘a’-'z'之间的字符,一共26个,所以我们借助一个长度为26的一维辅助数组(position)存储对应元素在数组中最近一次出现的位置。

如果当前元素在position数组中对应值为-1 或者  当前元素位置与该元素最近一次出现的位置 距离distance > 当前子串长度,则当前元素可加入子串,子串长度+1,继续往下走。

否则,distance < 当前子串长度,说明当前元素在子串中出现过了,则当前元素不能加入子串。

代码如下:

package offer.coder;

public interface TheMaxNoRepeatString48 {
	public static void main(String[] args) {
		System.out.println(getMaxNoRepeatString("arabcacfr"));

	}

	public static int getMaxNoRepeatString(String str){
		if("".equals(str) || str.length() == 0){
			return 0;
		}
		int[] position = new int[26];
		
		//初始化位置数组position
		for(int i = 0; i < position.length; i++){
			position[i] = -1;
		}
		
		int maxLength = 0;
		int curLength = 0;
		
		for(int i = 0; i < str.length(); i++){
			int index = str.charAt(i) - 'a'; // 定位元素在数组中的下标 
			int prePosition = position[index]; // 上一个元素出现的位置
			int distance = i - prePosition; // 计算此次出现距上次出现的距离
			if(prePosition < 0 || distance > curLength)  //距离>当前长度 ; 忽略,长度+1,继续判断下一个元素
				curLength++;
			else			
				curLength = distance;
	
			maxLength = maxLength > curLength ? maxLength : curLength;
			position[index] = i;			
		}
		return maxLength ;
	}
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章