zoukankan      html  css  js  c++  java
  • 315. Count of Smaller Numbers After Self

    You are given an integer array nums and you have to return a new counts array. 
    The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i]. Example: Given nums = [5, 2, 6, 1] To the right of 5 there are 2 smaller elements (2 and 1). To the right of 2 there is only 1 smaller element (1). To the right of 6 there is 1 smaller element (1). To the right of 1 there is 0 smaller element. Return the array [2, 1, 1, 0].

    bst: 加count记住遍历过得点有几个点比当前的点小(作为当前节点的左子树的节点数), 返回右父节点的所有count 和, 向左遍历(想好建好树后最后的点向哪遍历, 向左遍历, 第一个点就遍历了右边的所有的节点)

    Time: O(NlogN), space: O(N) better than naive solution O(N^2)

    public class Solution {
        private class TreeNode {
            public int val;
            public int count = 1;
            public TreeNode left, right;
            
            public TreeNode(int val) {
                this.val = val;
            }
        }
        
        public List<Integer> countSmaller(int[] nums) {
            List<Integer> res = new ArrayList<>();
            if(nums == null || nums.length == 0) {
                return res; 
            }
            TreeNode root = new TreeNode(nums[nums.length - 1]);
            res.add(0);
            
            for(int i = nums.length - 2; i >= 0; i--) {
                int count = addNode(root, nums[i]);
                res.add(count);
            }
            
            Collections.reverse(res);
            return res;
        }
        
        private int addNode(TreeNode root, int val) {
            int curCount = 0;
            while(true) {
                if(val <= root.val) {
                    root.count++;                   // add the inversion count
                    if(root.left == null) {
                        root.left = new TreeNode(val);
                        break;
                    } else {
                        root = root.left;
                    }
                } else {
                    curCount += root.count;
                    if(root.right == null) {
                        root.right = new TreeNode(val);
                        break;
                    } else {
                        root = root.right;
                    }
                }
            }
            
            return curCount;
        }
    }
    

      

    Merge sort: 老难了, 还是用bst吧

    public class Solution {
        int[] count;// 记录坐标的count
       //记录排序后的坐标, 就是nums[index[i]] 为排序后的值
        public List<Integer> countSmaller(int[] nums) {
            List<Integer> ans = new ArrayList<>();
            if (nums == null || nums.length == 0) {
                return ans;
            }
            count = new int[nums.length];
             int[] index = new int[nums.length];
            for (int i = 0; i < nums.length; i++) {
                index[i] = i;
            }
            mergSort(nums, 0, nums.length - 1, index);
            for (int i = 0; i < nums.length; i++) {
                ans.add(count[i]);
            }
            return ans;
            
        }
        private void mergSort(int[] nums, int start, int end, int[] index)  {
            if (end <= start) return;
            int mid = start + (end - start) / 2;
            mergSort(nums, start, mid, index);
            mergSort(nums, mid + 1, end, index);
            merg(nums, start, end, index);
        }
        private void merg(int[] nums, int start, int end, int[] index) {
            int mid = start + (end - start) / 2;
            int left = start, right = mid + 1, newStart = 0, sum = 0;
            int[] newIndex = new int[end - start + 1]; // 对坐标排序
            while (left <= mid && right <= end) {
                if (nums[index[right]] < nums[index[left]]) {
                    sum++;
                    newIndex[newStart++] = index[right++];
                } else  {
                    count[index[left]] += sum;
                    newIndex[newStart++] = index[left++];
                }
            }
            while (left <= mid) {
                count[index[left]] += sum;
                newIndex[newStart++] = index[left++];
            } 
            while (right <= end) {
                newIndex[newStart++] = index[right++];
            }
            for (int i = start; i <= end; i++) {
                index[i] = newIndex[i - start];
            }
            
        }
    }
    

      

  • 相关阅读:
    php tp6 踩坑(1)使用cookie助手函数 接口报500错误,但却没用错误信息问题
    php 杂项(2)--md5加密
    php tp6学习笔记(100) 正则表达式
    php 杂项(1)--单引号和双引号的区别
    pins和ports区别
    analyze&elaborate
    编译前后保存database
    DC层次化设计
    synthesis建立和保存
    DC综合过程和目标
  • 原文地址:https://www.cnblogs.com/apanda009/p/7298336.html
Copyright © 2011-2022 走看看