• LeetCode---Sort && Segment Tree && Greedy


    307. Range Sum Query - Mutable
    思路:利用线段树,注意数据结构的设计以及建树过程利用线段树,注意数据结构的设计以及建树过程
    public class NumArray {
    
    class segmentNode{
        int start;
        int end;
        segmentNode left;
        segmentNode right;
        int sum;
    
        public segmentNode(int start,int end){
            this.start = start;
            this.end = end;
            this.left = null;
            this.right = null;
            this.sum = 0;
        }
    }
    
    segmentNode root = null;
    
    public NumArray(int[] nums) {
        root = buildTree(nums,0,nums.length - 1);
    }
    
    public segmentNode buildTree(int[] nums,int start,int end){
        if(start > end) return null;
        else{
            segmentNode node = new segmentNode(start,end);
            if(start == end) node.sum = nums[start];
            else{
                int middle = start + (end - start) / 2;
                node.left = buildTree(nums,start,middle);
                node.right = buildTree(nums,middle + 1,end);
                node.sum = node.left.sum + node.right.sum;
            }
            return node;
        }
    }
    
    void update(int i, int val) {
        update(i,root,val);
    }
    
    public void update(int i,segmentNode root,int val){
        if(i == root.start && i == root.end) root.sum = val;
        else{
            int middle = root.start + (root.end - root.start) / 2;
            if(i <= middle){
                update(i,root.left,val);
            }
            else{
                update(i,root.right,val);
            }
            root.sum = root.left.sum + root.right.sum;
        }
    }
    
    public int sumRange(int i, int j) {
        return sumRange(i,j,root);
    }
    
    public int sumRange(int i,int j,segmentNode root){
        if(i == root.start && j == root.end) return root.sum;
        else{
            int middle = root.start + (root.end - root.start) / 2;
            if(i > middle) return sumRange(i,j,root.right);
            else if(j <= middle) return sumRange(i,j,root.left);
            else return sumRange(i,middle,root.left) + sumRange(middle + 1,j,root.right);
        }
    }
    }
    
    376. Wiggle Subsequence
    思路:首先跳过前面所有相等的元素,然后确定第一个是升序还是降序,接着利用贪心算法若降序取最小,若升序取最大,统计个数
    public int wiggleMaxLength(int[] nums) {
        if(nums.length <= 1) return nums.length;
        int num = nums[0];
        int k = 1;
        while(k < nums.length){
            if(nums[k] == num) k++;
            else break;
        }
        if(k == nums.length) return 1;
        
        int res = 2;
        //继续用k是因为要跳过之前相等的元素
        boolean flag = (nums[k] > nums[k - 1]);
        //k++;
        while(++k < nums.length){
            if(flag && nums[k] < nums[k - 1]){
                flag = false;
                res++;
            }
            else if(!flag && nums[k] > nums[k - 1]){
                flag = true;
                res++;
            }
            //k++;
        }
        return res;
    }
    
    **406. Queue Reconstruction by Height
    思路:按第一元素从大到小排,第二元素从小到大排,进行插入,第二元素实际上就是 插入的索引位置  
    
    public int[][] reconstructQueue(int[][] people) {
        if(people.length == 0) return new int[0][0];
        Arrays.sort(people,new Comparator<int[]>(){
            @Override
            public int compare(int[] a,int[] b){
                if(a[0] == b[0]){
                    return a[1] - b[1]; 
                }
                return b[0] - a[0];
            }
        });
        
        List<int[]> temp = new ArrayList<int[]>();
        for(int i = 0; i < people.length; i++){
            int[] ans = people[i];
            temp.add(ans[1],new int[]{ans[0],ans[1]});
        }
        
        int[][] res = new int[people.length][people[0].length];
        int i = 0;
        for(int[] k : temp){
            res[i][0] = k[0];
            res[i][1] = k[1];
            i++;
        }
        return res;
    }
    
    **330. Patching Array
    思路:用sum标记可达区间的右区间,若元素大于sum则补一个sum,否则扩大可达区间
    
    public int minPatches(int[] nums, int n) {
        //sum标记可达区间的右区间,开区间
        long sum = 1;//为了防止最后越界将sum设置为long
        int i = 0;
        int count = 0;
        while(sum <= n){
            if(i < nums.length && sum >= nums[i]){
                sum += nums[i];
                i++;
            }
            else{
                //表示1---sum - 1都可达,所以要补个sum
                sum += sum;
                count++;
            }
        }
        return count;
    }
    
    总结
    164. Maximum Gap:排序以后进行比较找到最大间隔
    56. Merge Intervals:同57
    455. Assign Cookies:两个数组排序以后进行遍历,前面判断过的不再考虑,因为绝对不会符合条件
    
    训练
    179. Largest Number:通过string排序,让a + b和b + a进行比较,谁大排在前面,注意string之间的比较用compareTo,不能直接-,另外注意特殊情况(开头为0)  
    **57. Insert Interval:将new Interval加入list一起根据start从小到大排序,通过判断start与end的关系进行合并,注意可以直接利用Collections.sort()
    452. Minimum Number of Arrows to Burst Balloons:根据start排序,若有交集则记录最小end,若没有则计数加一
    134. Gas Station:根据代数关系得知必须油的总量大于路程耗油量才行,因此只需要找到能到数组末尾站的站点即可
    **435. Non-overlapping Intervals:根据end从小到大排序,然后统计留下interval的数量,再用总数去减
    135. Candy:先给每个孩子发一个糖,利用Arrays.fill(),然后两趟循环分别判断左右两边的关系
    
    提示
    数组排序用Arrays.sort(),抽象数据结构排序用Collections.sort()
    优先队列排序直接在声明的时候就能定义排序方式,但注意优先队列的排序方式是堆排序
  • 相关阅读:
    有效的括号
    数组
    复杂度分析
    技术派-epoll和IOCP之比较
    2020 University Rankings US News(美国)
    2020 University Rankings US News(亚洲)
    2020 University Rankings US News(中国)
    技术派-如果编译提示winnt.h(222):error C2146错误
    技术派-github常见的一些用法和缩写
    技术派-9个常用的代码托管平台
  • 原文地址:https://www.cnblogs.com/LeonNew/p/6351443.html
Copyright © 2020-2023  润新知