Jerry's Blog

Recording what I learned everyday

View on GitHub


6 October 2019

LeetCode(29) -- 697, 700, 703

by Jerry Zhang

P697. Degree of an Array (Easy)

非空数组,最大的频度叫做它的degree。找到最小的连续子数组的长度,满足它的degree跟原数组的degree相同。

Input: [1, 2, 2, 3, 1]
Output: 2
Explanation:
The input array has a degree of 2 because both elements 1 and 2 appear twice.
Of the subarrays that have the same degree:
[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]
The shortest length is 2. So return 2.

我的思路

把每个数放到hashmap里, 记录它的出现频率,第一次出现的坐标以及最后一次出现的坐标。

我的代码

public class E_697_DegreeOfAnArray {
    public int findShortestSubArray(int[] nums) {
        HashMap<Integer, Integer[]> map = new HashMap<>();
        int degree = 0, ans = Integer.MAX_VALUE;
        List<Integer> degreeElements = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            Integer[] info = new Integer[3];
            if (map.containsKey(nums[i])) {
                info = map.get(nums[i]);
                info[0]++;
                info[2] = i;
            } else {
                info[0] = 1;
                info[1] = i;
            }
            if (info[0] > degree) {
                degree = info[0];
                degreeElements.clear();
                degreeElements.add(nums[i]);
            } else if (info[0] == degree) {
                degreeElements.add(nums[i]);
            }
            map.put(nums[i], info);
        }
        for (Integer degreeElement : degreeElements) {
            Integer[] info = map.get(degreeElement);
            if (info[2] == null) {
                ans = Math.min(ans, 1);
            } else {
                ans = Math.min(ans, info[2] - info[1] + 1);
            }
        }
        return ans;
    }
}

42%

答案

class Solution {
    public int findShortestSubArray(int[] nums) {
        Map<Integer, Integer> left = new HashMap(),
            right = new HashMap(), count = new HashMap();

        for (int i = 0; i < nums.length; i++) {
            int x = nums[i];
            if (left.get(x) == null) left.put(x, i);
            right.put(x, i);
            count.put(x, count.getOrDefault(x, 0) + 1);
        }

        int ans = nums.length;
        int degree = Collections.max(count.values());
        for (int x: count.keySet()) {
            if (count.get(x) == degree) {
                ans = Math.min(ans, right.get(x) - left.get(x) + 1);
            }
        }
        return ans;
    }
}

最优解

class Solution {
    public int findShortestSubArray(int[] nums) {
        //bucket sort;
        int max = Integer.MIN_VALUE;
        for(int i : nums) {
            max = Math.max(max, i);
        }
        int[] bucket = new int[max+1];
        int[] firstIndex = new int[max+1];
        int[] lastIndex = new int[max+1];
        int degree = 0;
        for(int i=0; i<nums.length; i++) {
            bucket[nums[i]]++;
            if(bucket[nums[i]] == 1) {
                firstIndex[nums[i]] = i;
                lastIndex[nums[i]] = i;
            }else{
                lastIndex[nums[i]] = i;
            }
            degree = Math.max(degree, bucket[nums[i]]);
        }
        int ret = Integer.MAX_VALUE;
        for(int i=0; i<bucket.length; i++) {
            if(bucket[i] == degree) {
                ret = Math.min(lastIndex[i] - firstIndex[i] + 1, ret);
            }
        }
        return ret;
    }
}

手工HashMap(bucket)

P700. Search in a Binary Search Tree (Easy)

在一个BST中寻找某个值的子节点。

我的思路

BST最基本的遍历。

我的代码

public class E_700_SearchinaBinarySearchTree {
    public TreeNode searchBST(TreeNode root, int val) {
        if (root == null) {
            return null;
        }
        if (root.val == val) {
            return root;
        }
        if (val < root.val) {
            return searchBST(root.left, val);
        }
        return searchBST(root.right, val);
    }
}

100%

最优解

class Solution {
    public TreeNode searchBST(TreeNode root, int val) {

        return searchBST1(root, val);

    }
    public TreeNode searchBST1(TreeNode root, int val)
    {
        if(root == null) return null;

        if(root.val == val){
            return root;
        }

        if(val < root.val)
            return searchBST1(root.left, val);
        else
            return searchBST1(root.right, val);

    }
}

P703. Kth Largest Element in a Stream (Easy)

一个流中第k大的数

我的思路

看答案用min heap。

讨论区

class KthLargest {

    private Queue<Integer> pq;
    private int k;

    public KthLargest(int k, int[] nums) {
        pq = new PriorityQueue<>(k);
        this.k = k;
        for (int num : nums) {
            add(num);
        }
    }

    public int add(int val) {
        pq.add(val);
        if (pq.size() == k + 1) {
            pq.remove();
        }
        return pq.peek();
    }
}

最优解

class KthLargest {

    public int[] nums;
    public int len, k;

    public KthLargest(int k, int[] nums) {
        this.nums = new int[k + 1];
        len = 0;
        this.k = k;
        for (int i = 0; i < nums.length; i++)
            insert(nums[i]);
    }

    public int add(int val) {
        insert(val);
        return nums[0];
    }

    public void insert(int number)
    {
        if (len < k){
            nums[len] = number;
            moveUp(len++);
        }
        else {
            if (nums[0] < number){
                nums[0] = number;
                moveDown(0);
            }
        }

    }

    public void moveUp(int index)
    {
        if (index == 0)
            return;
        int fatherIndex = (index - 1) / 2;
        if (nums[index] < nums[fatherIndex])
        {
            int temp = nums[index];
            nums[index] = nums[fatherIndex];
            nums[fatherIndex] = temp;
            moveUp(fatherIndex);
        }
    }

    public void moveDown(int index)
    {
        if (index * 2 + 2 < len)
        {
            int leftChild = index * 2 + 1;
            int rightChild = index * 2 + 2;
            if ((nums[leftChild] < nums[index])&&(nums[leftChild] <= nums[rightChild]))
            {
                int temp = nums[index];
                nums[index] = nums[leftChild];
                nums[leftChild] = temp;
                moveDown(leftChild);
            }
            else if ((nums[rightChild] < nums[index])&&(nums[rightChild] <= nums[leftChild]))
            {
                int temp = nums[index];
                nums[index] = nums[rightChild];
                nums[rightChild] = temp;
                moveDown(rightChild);
            }
        }
        else if (index * 2 + 2 == len)
        {
            int leftChild = index * 2 + 1;
            if (nums[leftChild] < nums[index])
            {
                int temp = nums[index];
                nums[index] = nums[leftChild];
                nums[leftChild] = temp;
                moveDown(leftChild);
            }
        }
    }
}
tags: LeetCode