美文网首页
[LeetCode 315] Count Of smaller

[LeetCode 315] Count Of smaller

作者: 灰睛眼蓝 | 来源:发表于2019-05-20 08:08 被阅读0次

Solution:

  1. 如果直接对数组求解,那么时间复杂度是O(n sqr)
  2. 可以将数组reverse一次,这样的话,求到5的时候,1和2已经访问过了,而且已知是小于5的,直接可以得出答案。
  3. 可以借助Binary Index Tree,利用prefix sum of frequency, 将数组中每个数转换成它的rank(第i小的数) ,并将该 rank出现的frequency作为Binary Index Tree中的sum数组。
  4. 那么问题就转换成了,对数组根据其rank求其prefix sum of frequency

1. Binary Index Tree

  • int[] sum = new int [n unique number count + 1]: 每个rank的frequency
  • updateTree
  • queryTree

2. 求解

1)Get SortedSet uniqueNumbers = new TreeSet<> (), 并用given numbers 初始化该UniqueNumbers
2)Get UniqueNumber vs Ranking map

Map<Integer, Integer> uniqueNums2Rank = new HashMap<> ();
        int rank = 0;
        
        for (int num : uniqueNums) {
            rank++;
            uniqueNums2Rank.put (num, rank);
        }
  1. reverse numbers,然后对每个数,从Binary Index Treequery (Rank - 1)。即求,在其之前出现的,rank比其小的数,出现的frequency之和,将其推入result;然后更新frequency table,即更新Binary Index Tree
  2. reverse result (因为是基于reversed的numbers来求解的)
image.png
class FenwickTree {
    private int[] sum;
    public FenwickTree (int n) {
        sum = new int [n + 1];
    }
    
    public void updateTree (int i, int value) {
        while (i < sum.length) {
            sum [i] += value;
            i += i & -i;
        }
    }
    
    public int queryTree (int i) {
        int result = 0;
        
        while (i > 0) {
            result += sum [i];
            i -= i & -i;
        }
        
        return result;
    }
}

class Solution {
    public FenwickTree tree;
    
    
    public List<Integer> countSmaller(int[] nums) {
        List<Integer> result = new ArrayList<> ();
        if (nums == null || nums.length == 0) {
            return result;
        }
        
        
        //1. create the fenwick tree
        tree = new FenwickTree (nums.length);
        
        //2. get the unique number set
        SortedSet<Integer> uniqueNums = new TreeSet<> ();
        for (int num : nums) {
            uniqueNums.add (num);
        }
        
        
        //3. get the unique number vs its rank map
        Map<Integer, Integer> uniqueNums2Rank = new HashMap<> ();
        int rank = 0;
        
        for (int num : uniqueNums) {
            rank++;
            uniqueNums2Rank.put (num, rank);
        }
        
        //4. trying to find the count of smaller number after self based on the frequency of each rank of number
        //4.1 Based on reverse sort
        
        for (int i = nums.length - 1; i >= 0; i--) {
            int currentRank = uniqueNums2Rank.get (nums [i]);
            int currentCountOfSmallerNumber = tree.queryTree (currentRank - 1);
            result.add (currentCountOfSmallerNumber);
            
            tree.updateTree (currentRank, 1);
        }
        
        //5. reverse the result, becasue it's based on the reversed numbers
        Collections.reverse (result);
        return result;
    }
}

相关文章

网友评论

      本文标题:[LeetCode 315] Count Of smaller

      本文链接:https://www.haomeiwen.com/subject/owqhzqtx.html