
题目描述
给定一个整数数组 nums,你可以执行任意次下面的操作:
您的任务是找到使数组为 空 所需的 最小 操作数。
 
示例 1:
输入:nums = [5,3,1,4,2]
输出:3
解释:
我们删除子序列 [1, 2],[3, 4],[5]。
 
示例 2:
输入:nums = [1,2,3,4,5]
输出:1
 
示例 3:
输入:nums = [5,4,3,2,1]
输出:5
 
 
提示:
    1 <= nums.length <= 105 
    1 <= nums[i] <= 105 
解法
方法一:贪心 + 二分查找
我们从左到右遍历数组 \(\textit{nums}\),对于每个元素 \(x\),我们需要贪心地将其追加到前面序列中最后一个元素小于 \(x\) 的最大值后面。如果找不到这样的元素,则说明当前元素 \(x\) 比前面序列中的所有元素都小,我们需要新开辟一个序列,将 \(x\) 放入其中。
这样分析下来,我们可以发现,前面序列中的最后一个元素呈单调递减的状态。因此,我们可以使用二分查找来找到前面序列中最后一个元素小于 \(x\) 的第一个元素位置,然后将 \(x\) 放入该位置。
最终,我们返回序列的个数即可。
时间复杂度 \(O(n \times \log n)\),空间复杂度 \(O(n)\)。其中 \(n\) 为数组 \(\textit{nums}\) 的长度。
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16  | class Solution:
    def minOperations(self, nums: List[int]) -> int:
        g = []
        for x in nums:
            l, r = 0, len(g)
            while l < r:
                mid = (l + r) >> 1
                if g[mid] < x:
                    r = mid
                else:
                    l = mid + 1
            if l == len(g):
                g.append(x)
            else:
                g[l] = x
        return len(g)
  | 
 
 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22  | class Solution {
    public int minOperations(int[] nums) {
        List<Integer> g = new ArrayList<>();
        for (int x : nums) {
            int l = 0, r = g.size();
            while (l < r) {
                int mid = (l + r) >> 1;
                if (g.get(mid) < x) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            if (l == g.size()) {
                g.add(x);
            } else {
                g.set(l, x);
            }
        }
        return g.size();
    }
}
  | 
 
 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23  | class Solution {
public:
    int minOperations(vector<int>& nums) {
        vector<int> g;
        for (int x : nums) {
            int l = 0, r = g.size();
            while (l < r) {
                int mid = (l + r) >> 1;
                if (g[mid] < x) {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            if (l == g.size()) {
                g.push_back(x);
            } else {
                g[l] = x;
            }
        }
        return g.size();
    }
};
  | 
 
 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20  | func minOperations(nums []int) int {
    g := []int{}
    for _, x := range nums {
        l, r := 0, len(g)
        for l < r {
            mid := (l + r) >> 1
            if g[mid] < x {
                r = mid
            } else {
                l = mid + 1
            }
        }
        if l == len(g) {
            g = append(g, x)
        } else {
            g[l] = x
        }
    }
    return len(g)
}
  | 
 
 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20  | function minOperations(nums: number[]): number {
    const g: number[] = [];
    for (const x of nums) {
        let [l, r] = [0, g.length];
        while (l < r) {
            const mid = (l + r) >> 1;
            if (g[mid] < x) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }
        if (l === g.length) {
            g.push(x);
        } else {
            g[l] = x;
        }
    }
    return g.length;
}
  | 
 
 
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23  | impl Solution {
    pub fn min_operations(nums: Vec<i32>) -> i32 {
        let mut g = Vec::new();
        for &x in nums.iter() {
            let mut l = 0;
            let mut r = g.len();
            while l < r {
                let mid = (l + r) / 2;
                if g[mid] < x {
                    r = mid;
                } else {
                    l = mid + 1;
                }
            }
            if l == g.len() {
                g.push(x);
            } else {
                g[l] = x;
            }
        }
        g.len() as i32
    }
}
  |