14- I. 剪绳子
法一:
动态规划。
1.dp[2]=1;
2.对于总长度为i的绳子,假设减去了长度为j的一段,若剩下的绳子不再继续剪,则乘积为j*(i-j);若剩下的绳子继续剪,则乘积为j * dp[i-j]。j可以取值为2~i-1,最大乘积为max(dp[i], j*(i-j), j*dp[i-j])。
class Solution {
public int cuttingRope(int n) {
int[] dp = new int[n + 1];
//长度为2的绳子,最大乘积为1
dp[2] = 1;
for(int i = 3; i <= n; ++i){
for(int j = 2; j < i; ++j){
dp[i] = Math.max(dp[i], j * (i - j));
dp[i] = Math.max(dp[i], j * dp[i-j]);
}
}
return dp[n];
}
}
法二:
贪心法。
将绳子分为尽可能多的3。
class Solution {
public int cuttingRope(int n) {
if(n < 4){
return n - 1;
}
int res = 1;
while(n > 4){
n = n - 3;
res *= 3;
}
res *= n;
return res;
}
}
53 - II. 0~n-1中缺失的数字
算法思想:
代码:
排序数组中的搜索问题,首先想到二分法解决。
i=0,j=n.length-2,m=i+j
若n[m]!=m说明左子数组的最后一个元素在0~m-1区间,令j=m-1;
若n[m]=m说明右子数组的首元素在m+1~n.length-1区间,令i=m+1;
循环跳出条件为i指向右子数组首元素,j指向左子数组末元素,即i>j时跳出。
class Solution {
public int missingNumber(int[] nums) {
int i = 0, j = nums.length - 1;
while(i <= j){
int m = (i + j) / 2;
if(nums[m] == m){
i = m + 1;
}else{
j = m - 1;
}
}
return i;
}
}