leetcode做题总结,贪心算法I

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;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值