1. 跳跃游戏
2. 视频拼接
3. 剪绳子I
4. 把数字翻译成字符串
1. 跳跃游戏
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
--------------------------------------------------------------------------------
思路:遍历数组,维护一个max表示目前最远能跳到的位置
class Solution {
public boolean canJump(int[] nums) {
int max = 0;
for(int i = 0; i< nums.length; i++){
if(i > max) return false;
int temp = nums[i] +i;
if(temp >= nums.length) return true;
if( temp > max) max = temp;
}
return true; //如果出现[0]这种输入
}
}
2. 视频拼接
输入:clips = [[0,2],[1,9],[1,5],[4,6],[5,9],[8,10]], T = 10
输出:3
解释:
我们选中 [0,2], [8,10], [1,9] 这三个片段。
然后,按下面的方案重制比赛片段:
将 [1,9] 再剪辑为 [1,2] + [2,8] + [8,9] 。
现在我们手上有 [0,2] + [2,8] + [8,10],而这些涵盖了整场比赛 [0, 10]。
-----------------------------------------------------------------------------
思路:dp[i]表示从i开始能到的最远的位置
该例子中dp[] = {2,9,0,0,6,9,0,0,10,0,0}
遍历数组,max记录下目前能到的最远的位置,pre记录上一个位置,ans记录答案
i = 0: max =2,pre = 0, 因为pre == i; ans++,表示需要[0,2]; pre = max,表示目前最远的是2
i = 1: max = 9,pre = 2,因为目前可以到2,现在i<2,先不急着ans++,万一存在[2,10],就不需要[1,9]了,继续观望,一直到pre == i,我们才做最后的打算
class Solution {
public int videoStitching(int[][] clips, int T) {
int[] dp = new int[T+1];
int a,b; //临时变量
int temp; //临时变量
//下面都在计算dp
for(int i = 0; i < clips.length; i++){
a = clips[i][0];
if(a > T) continue;
b = clips[i][1];
temp = b > T? T: b;
dp[a] = Math.max(dp[a], temp);
}
int max = 0;
int pre = 0;
int ans = 0;
for(int i =0; i< T+1; i++){
max = Math.max(max,dp[i]);
if(max == T) return ans+1;
if(pre == i){
ans++;
pre = max;
}
if(max == i) return -1;
}
return ans;
}
}
3. 剪绳子I
给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]...k[m-1] 。请问 k[0]*k[1]*...*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18
输入: 10
输出: 36
解释: 10 = 3 + 3 + 4, 3 × 3 × 4 = 36
---------------------------------------------------------
思路:当n>=5的时候,剪成2或者3肯定比剪大的划算。
比如:n=13时,单独剪一个6出来,肯定不如2*2*2来的划算
class Solution {
public int cuttingRope(int n) {
int[] dp = new int[n+1];
if(n == 2) return 1;
if(n == 3) return 2;
if(n == 4) return 4;
dp[2] = 2;
dp[3] = 3;
dp[4] = 4;
int temp1, temp2;
for(int i = 5; i<=n ; i++){
temp1 = 3 * dp[i-3];
temp2 = 2 * dp[i-2];
dp[i] = temp1> temp2? temp1: temp2;
}
return dp[n];
}
}
4. 把数字翻译成字符串
给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。
输入: 12258
输出: 5
解释: 12258有5种不同的翻译,分别是"bccfi", "bwfi", "bczi", "mcfi"和"mzi"
----------------------------------------------------
思路:dp[i]表示到第i个字符一共有多少种答案
以12258为例
初始化dp[0],dp[1]
dp[0] = 1;
dp[1] = 2; 因为 12<=25
当字符i和i-1大于等于10并且小于25,dp[i] = dp[i-1] +dp[i]
不然 dp[i] = dp[i-1]
class Solution {
public int translateNum(int num) {
if(num < 10) return 1;
int n = 0;
int temp = num;
while(temp > 0){
temp = temp/10;
n++;
}
int[] dp = new int[n];
String str = String.valueOf(num);
dp[0] = 1;
int first = (str.charAt(0) - '0') * 10 + str.charAt(1) - '0';
if(first <= 25) dp[1] = 2;
else dp[1] = 1;
for(int i =2; i<n; i++){
int temp1 = (str.charAt(i-1) - '0') * 10 + str.charAt(i) - '0';
//System.out.println("temp = "+ temp1);
if(temp1 <= 25 && temp1 >= 10) dp[i] = dp[i-1] + dp[i-2];
else dp[i] = dp[i-1];
}
//for(int num1: dp){
// System.out.println(num1);
//}
return dp[n-1];
}
}