Leetcode 300

原文鏈接:https://leetcode.com/problems/longest-increasing-subsequence/

關於 Arrays.binarySearch() 方法的分析

題目:Leetcode 300
Given an unsorted array of integers, find the length of longest increasing subsequence.

Example:

Input: [10,9,2,5,3,7,101,18]
Output: 4
Explanation: The longest increasing subsequence is [2,3,7,101], therefore the length is 4.

Note:

There may be more than one LIS combination, it is only necessary for you to return the length.
Your algorithm should run in O(n2) complexity.

Follow up: Could you improve it to O(n log n) time complexity?

——————————————————————————————————————————————————————————
在這種方法中,我們從左到右掃描數組。
我們還使用一個用所有0初始化的dp數組。這個dp數組用於存儲通過包含當前遇到的元素而形成的遞增子序列
在遍歷nums數組時,我們繼續用到目前爲止遇到的元素填充dp數組。對於與j索引(nums[j])相對應的元素,我們通過使用二叉搜索算法 (由於dp數組存儲的是增加的子序列,因此可以使用二叉搜索算法)來確定其在dp數組中的正確位置(例如,i索引),並將其插入正確的位置。
需要注意的一點是,對於二叉搜索算法,我們只考慮dp數組中通過在正確位置插入一些元素(始終保持排序)進行更新的部分。因此,只有dp數組中的第i個索引以上的元素才能確定當前元素在其中的位置。由於元素在dp數組中以升序進入其正確position(i),因此迄今爲止在該元素中形成的子序列肯定是一個遞增的子序列。每當這個位置索引i等於到目前爲止LIS的長度(len)時,就意味着我們需要更新len爲len=len+1
注意:dp數組不會導致最長子序列的增加,但是dp數組的長度會給您LIS的長度。
Consider the example:
input: [0, 8, 4, 12, 2]
dp: [0]
dp: [0, 8]
dp: [0, 4]
dp: [0, 4, 12]
dp: [0 , 2, 12] 這並不是最長的遞增子序列,但是dp數組的長度是最長遞增子序列的長度。
注意:Arrays.binarySearch()方法返回索引的搜索鍵,如果它是包含在數組,其他它返回 (-(insertion point) - 1)。的插入點是點關鍵將插入數組:第一個元素的索引大於鍵,或。如果數組中的所有元素都小於指定的鍵,則爲長度。

public class Solution {
    public int lengthOfLIS(int[] nums) {
        int[] dp = new int[nums.length];
        int len = 0;
        for (int num : nums) {
            int i = Arrays.binarySearch(dp, 0, len, num);
            if (i < 0) {
                i = -(i + 1);
            }
            dp[i] = num;
            if (i == len) {
                len++;
            }
        }
        return len;
    }
}

Complexity Analysis

Time complexity :
O(nlogn). Binary search takes nlogn time and it is called n times.

Space complexity :
O(n). dp array of size n is used.

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