LeetCode 315 逆序對(java)

一、題目分析

count[i]表示在nums[i]右側且比它小的元素個數 

下面是構造成樹的思路

yi 

 

 

 

還有一種方法是歸併排序 

二、代碼 

方法1:搜索二叉樹

class TreeNode {
    int val;
    int size;
    TreeNode left, right;
    TreeNode(int val) {
        this.val = val;
    }
}
public class Solution {
    TreeNode root;
    private int smaller(TreeNode current, int val) {
        current.size ++;
         if (current.val < val) {
             if (current.right == null) current.right = new TreeNode(val);
             return current.size - 1 - current.right.size + smaller(current.right, val);
         } else if (current.val > val) {
             if (current.left == null) current.left = new TreeNode(val);
             return smaller(current.left, val);
         } else {
             return current.left == null? 0 : current.left.size;
         }
    }
    public List<Integer> countSmaller(int[] nums) {
        List<Integer> result = new ArrayList<>(nums.length);
        int[] smaller = new int[nums.length];
        if (nums == null || nums.length == 0) return result;
        root = new TreeNode(nums[nums.length-1]);
        for(int i=nums.length-1; i>=0; i--) {
            smaller[i] = smaller(root, nums[i]);
        }
        for(int i=0; i<smaller.length; i++) result.add(smaller[i]);
        return result;
    }
}

這裏是插入過程分成兩種,一個是插入值小於當前值,一個是插入值大於當前值 ,如果相等就沒有插入,而是直接返回一個值。當前結點的左子樹爲空返回0,否則返回左子樹的結點個數

然後前面的current.size++不好理解,我理解成每次來一個結點,先在current結點的size++,表示這個節點下連着的節點的個數,包括自己。所以val(待插入節點的值)大於current.val,要向右子樹插入,如果右子樹爲空,直接插入,否則遞歸查找到位置,返回值中current.size-1是因爲減去當前還沒有插入的節點,當前結點.size-1,再減去cu.right.size,就是right左邊有幾個節點小於right.val

 方法2:歸併排序

public class Solution {
    private void sort(int[] nums, int[] smaller, int[] pos, int from, int to) {
        if (from >= to) return;
        int m = (from + to) / 2;
        sort(nums, smaller, pos, from, m);
        sort(nums, smaller, pos, m+1, to);
        int[] merged = new int[to-from+1];
        int i=from, j=m+1, k=0, jump = 0;
        while (i<=m || j<=to) {
            if (i>m) {
                //jump ++;
                merged[k++] = pos[j++];
            } else if (j>to) {
                smaller[pos[i]] += jump;
                merged[k++] = pos[i++];
            } else if (nums[pos[i]] <= nums[pos[j]]) {
                smaller[pos[i]] += jump;
                merged[k++] = pos[i++];
            } else {
                jump ++;
                merged[k++] = pos[j++];
            }
        }
        for(int p=0; p<merged.length; p++) pos[from+p] = merged[p];
    }
    public List<Integer> countSmaller(int[] nums) {
        int[] smaller = new int[nums.length];
        int[] pos =new int[nums.length];
        for(int i=0; i<pos.length; i++) pos[i] = i;
        sort(nums, smaller, pos, 0, nums.length-1);
        List<Integer> result = new ArrayList<>(nums.length);
        for(int i=0; i<nums.length; i++) result.add(smaller[i]);
        return result;
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章