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()
优先队列排序直接在声明的时候就能定义排序方式,但注意优先队列的排序方式是堆排序

posted on 2017-01-26 11:52  LeonNew  阅读(194)  评论(0)    收藏  举报

导航