動態規劃問題: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 ;
	}
}

 

 

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