jump game II
这道题可以只历遍一次,然后纪录下每次能到达的最远距离。
public int jump(int[] A) {
int n = A.length;
int max=0,far=0,num=0;
for(int i=0;i<n;){
if(far>=n-1) return num;
while(i<=far){
max=Math.max(max,i+A[i]);
i++;
}
num++;
far=max;
}
return num;
}
Best Time to Buy and Sell Stock II/III
第二题很简单,无限次数买卖,只要每个低点买入,下一个高点卖出即可。
public int maxProfit(int[] prices) {
int n = prices.length;
int in=0,out=0,max=0,hold=0;
for(int i=0;i<n-1;i++){
if(hold==0&&prices[i+1]>prices[i]){
in=prices[i];
hold++;
}
if(hold==1&&prices[i+1]<prices[i]){
out=prices[i];
hold--;
max=max+(out-in);
}
}
if(hold==1){
out=prices[n-1];
hold--;
max=max+(out-in);
}
return max;
}
第三题和第一题差不多,用两个数组分解纪录0-i和i-n的最大获利,以前一个数组为例,对于点i,只需判断array[i-1]和i的值减去min谁大。后一个数组注意要从后往前计算,随后历遍求出每个点左右的最大获利加和。
public int maxProfit(int[] prices) {
if (prices.length == 0) {
return 0;
}
int n = prices.length;
int[] left=new int[n];
int[] right=new int[n];
int min=prices[0];
left[0]=0;
for(int i=1;i<n;i++){
left[i]=left[i-1]>prices[i]-min?left[i-1]:prices[i]-min;
if(prices[i]<min)min=prices[i];
}
right[n-1]=0;
int max=prices[n-1];
for(int i=n-2;i>=0;i--){
right[i]=right[i+1]>max-prices[i]?right[i+1]:max-prices[i];
if(prices[i]>max)max=prices[i];
}
int value = 0;
for (int i = 0; i < n; i++) {
value = value > left[i] + right[i] ? value : left[i] + right[i];
}
return value;
}
Maximum Subarray
这道题和上题的I一样,求最大子序列,只用历遍一次,从正数开头,累加,如果加和出现负数在前一点断掉继续里边寻找开头。
public int maxSubArray(int[] A) {
if(A.length==0) return 0;
int max=A[0],record=0;
boolean tmp=false;
for(int i=0;i<A.length-1;i++){
if(!tmp&&max<=0&&A[i]>max)max=A[i];
if(!tmp&&A[i]>0){
//start=i;
record=0;
tmp=true;
}
if(tmp&&((record+A[i]+A[i+1])>=0)){
record+=A[i];
max=max>record?max:record;
}else if(tmp&&((record+A[i]+A[i+1])<0)){
record+=A[i];
max=max>record?max:record;
record=0;
tmp=false;
}
}
if(tmp){
record+=A[A.length-1];
max=max>record?max:record;
}else{
max=max>A[A.length-1]?max:A[A.length-1];
}
return max;
}
Update 2015/08/27:上面的例子过于复杂了,这道题其实很简单,使用global和local两个变量即可。
public class Solution {
/**
* @param nums: A list of integers
* @return: A integer indicate the sum of max subarray
*/
public int maxSubArray(ArrayList<Integer> nums) {
// write your code
if (nums.size() == 0)
return 0;
int global = nums.get(0);
int local = nums.get(0);
if (local < 0)
local = 0;
for (int i = 1; i < nums.size(); i++){
if (local < 0)
local = 0;
local = Math.max(local + nums.get(i), nums.get(i));
global = Math.max(global, local);
}
return global;
}
}