Leetcode-Java(三十一)

303. Range Sum Query - Immutable

用一个数组保存从0到当前位置的和。

class NumArray {
    int[] sumnums;
    public NumArray(int[] nums) {
        
        if(nums.length==0)
            return;
        sumnums = new int[nums.length];
        sumnums[0] = nums[0];
        for(int i=1;i<nums.length;i++){
            sumnums[i] = sumnums[i-1] + nums[I];
        }
    }
    
    public int sumRange(int i, int j) {
        if(i==0)
            return sumnums[j];
        return sumnums[j] - sumnums[i-1];
    }
}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * int param_1 = obj.sumRange(i,j);
 */

304. Range Sum Query 2D - Immutable

借鉴303题的思路,同样构造一个求和的矩阵,行列关系共分为四种,需要仔细分析每种情况下的计算:

class NumMatrix {
    int[][] summatrix;
    public NumMatrix(int[][] matrix) {
        if(matrix==null || matrix.length==0)
            return;   
        summatrix = new int[matrix.length][matrix[0].length];
        for(int i=0;i<matrix.length;i++){
            for(int j=0;j<matrix[i].length;j++){
                if(i==0 && j==0)
                    summatrix[i][j] = matrix[i][j];
                else if(i==0)
                    summatrix[i][j] = summatrix[i][j-1] + matrix[i][j];
                else if(j==0)
                    summatrix[i][j] = summatrix[i-1][j] + matrix[i][j];
                else
                    summatrix[i][j] = summatrix[i-1][j] + summatrix[i][j-1] - summatrix[i-1][j-1] + matrix[i][j];
            }
        }
    }
    
    public int sumRegion(int row1, int col1, int row2, int col2) {
        if(row1==0 && col1==0)
            return summatrix[row2][col2];
        else if(row1==0)
            return summatrix[row2][col2] - summatrix[row2][col1-1];  
        else if(col1==0)
            return summatrix[row2][col2] - summatrix[row1-1][col2];
        else
            return summatrix[row2][col2] - summatrix[row1-1][col2] - summatrix[row2][col1-1] + summatrix[row1-1][col1-1];
    }
}

/**
 * Your NumMatrix object will be instantiated and called as such:
 * NumMatrix obj = new NumMatrix(matrix);
 * int param_1 = obj.sumRegion(row1,col1,row2,col2);
 */

307. Range Sum Query - Mutable

这里同303题,用另一个数组保存了原数组中每个元素的值,每次更新的时候,不要忘记将该位置对应元素的值进行更新。

class NumArray {
    int[] sumnums;
    int[] orgnums;
    public NumArray(int[] nums) {
        if(nums==null || nums.length==0)
            return;
        sumnums = new int[nums.length];
        sumnums[0] = nums[0];
        orgnums = new int[nums.length];
        orgnums[0] = nums[0];
        for(int i=1;i<nums.length;i++){
            sumnums[i] = sumnums[i-1] + nums[I];
            orgnums[i] = nums[I];
        }
    }
    
    public void update(int i, int val) {
        for(int j=i;j<sumnums.length;j++){
            sumnums[j] += (val - orgnums[I]);
        }
        orgnums[i] = val;
    }
    
    public int sumRange(int i, int j) {
        if(i==0)
            return sumnums[j];
        return sumnums[j] - sumnums[i-1];
    }
}

/**
 * Your NumArray object will be instantiated and called as such:
 * NumArray obj = new NumArray(nums);
 * obj.update(i,val);
 * int param_2 = obj.sumRange(i,j);
 */

309. Best Time to Buy and Sell Stock with Cooldown

使用回溯法,超时。。

class Solution {
    int maxProfit = 0;
    public int maxProfit(int[] prices) {
        backprop(prices,0,0,0,0);
        return maxProfit;
    }
    public void backprop(int[] prices,int start,int profit,int buyPrice,int type){
        if(start >= prices.length){
            maxProfit = Math.max(maxProfit,profit);
        }
        if(type==0){
            for(int i=start;i<prices.length;i++){
                backprop(prices,i+1,profit,prices[i],1);
            }
        }
        else if(type==1){
            for(int i=start;i<prices.length;i++){
                backprop(prices,i+2,profit + (prices[i]-buyPrice),0,0);
            }
        }
    }
}

此题需要维护三个一维数组buy, sell,和rest。其中:
buy[i]表示在第i天之前最后一个操作是买,此时的最大收益。
sell[i]表示在第i天之前最后一个操作是卖,此时的最大收益。
rest[i]表示在第i天之前最后一个操作是冷冻期,此时的最大收益。

我们写出递推式为:

buy[i]  = max(rest[i-1] - price, buy[i-1]) 
sell[i] = max(buy[i-1] + price, sell[i-1])
rest[i] = max(sell[i-1], rest[i-1])

解读一下,第一个公式buy[i],如果第i天可以买,那么i-1天会是冷冻期,否则,不能进行购买,因此比较rest[i-1] - price和 buy[i-1]的大小。第二个公式sell[i],可以卖的条件是,i-1天之前最后一个操作时买入股票,否则,不能卖出,因此比较buy[i-1] + price和sell[i-1]。第三个式子,冷冻期的可能性有两个,一个是昨天刚进行卖的交易,另一个是继续冷冻期。

上述递推式很好的表示了在买之前有冷冻期,买之前要卖掉之前的股票。一个小技巧是如何保证[buy, rest, buy]的情况不会出现,这是由于buy[i] <= rest[i], 即rest[i] = max(sell[i-1], rest[i-1]),这保证了[buy, rest, buy]不会出现。

另外,由于冷冻期的存在,我们可以得出rest[i] = sell[i-1],这样,我们可以将上面三个递推式精简到两个:

buy[i]  = max(sell[i-2] - price, buy[i-1]) 
sell[i] = max(buy[i-1] + price, sell[i-1]) 

因此,代码如下:

class Solution {
    public int maxProfit(int[] prices) {
        if(prices==null || prices.length <2)
            return 0;
        int[] buy = new int[prices.length];
        int[] sell = new int[prices.length];
        buy[0] = -prices[0];
        buy[1] = Math.max(-prices[0],-prices[1]);
        sell[0] = 0;
        sell[1] = Math.max(0,prices[1]-prices[0]);
        for(int i=2;i<prices.length;i++){
            buy[i] = Math.max(sell[i-2] - prices[i],buy[i-1]);
            sell[i] = Math.max(buy[i-1] + prices[i],sell[i-1]);
        }
        return sell[prices.length-1];
    }
}

310. Minimum Height Trees

答案只可能有一个或两个节点。思路为依次删除叶子节点,剩下的1/2个节点即为解。
速度问题:如果每次遍历选出叶子节点,速度比较慢,可以每次删除当前叶子节点时,将新的叶子节点记录下来。

class Solution {
    public List<Integer> findMinHeightTrees(int n, int[][] edges) {
        List<Integer> leaves = new ArrayList<>();
        if(n <= 1) {
            return Collections.singletonList(0);
        }
        Map<Integer, Set<Integer>> graph = new HashMap<>();     // list of edges to  Ajacency Lists
        
        for(int i = 0; i < n; i++) {
            graph.put(i, new HashSet<Integer>());
        }
        for(int[] edge : edges) {
            graph.get(edge[0]).add(edge[1]);
            graph.get(edge[1]).add(edge[0]);
        }
        
        for(int i = 0; i < n; i++) {
            if(graph.get(i).size() == 1) {
                leaves.add(i);
            }
        }
        
        while(n > 2) {
            n -= leaves.size();
            List<Integer> newLeaves = new ArrayList<>();
            for(int leaf : leaves) {
                for(int newLeaf : graph.get(leaf)) {
                    graph.get(leaf).remove(newLeaf);
                    graph.get(newLeaf).remove(leaf);
                    if(graph.get(newLeaf).size() == 1) {
                        newLeaves.add(newLeaf);
                    }
                }
            }
            leaves = newLeaves;
        }
        
        return leaves;
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容