算法-删除元素后最大固定点数目-典型最长增长序列算法

题目

给你一个整数数组 nums

如果 nums[i] == i,则位置 i 被称为 固定点

允许你从数组中删除 任意 数量的元素(包括零个)。在每次删除后,剩余元素 向左移动,并且下标从 0 开始重新分配。

返回一个整数,表示在执行任意次数的删除操作后,可以获得的 最大 固定点数量。

示例 1:

输入: nums = 0,2,1

输出: 2

解释:

  • 删除 nums[1] = 2。数组变为 [0, 1]
  • 现在,nums[0] = 0nums[1] = 1,因此两个下标都是固定点。
  • 因此,答案为 2。

题解

思路学习:本题跟俄罗斯套娃信封问题的解题思路一致,解决本题核心思考:

要求i==numsi,当i增加的时候numsi也需要增加,也就是连续增长序列,也即本题求最长连续增长序列

当数组中numsi的元素x需要移动i-x步时,比x大的元素numsj=z需要的移动步数必须大于i-x步时才能让i,j同时成为固定点位,因为numsi移动的i-x步的时候,numsj也会移动的i-x步,如果numsj需要的移动步数小于numsi时,则两者不能同时成为固定点位。需要维护numi开始的最长增长序列长度和numsj开始的最长增长序列长度。

java 复制代码
class Solution {
    public int maxFixedPoints(int[] nums) {
        List<int[]> a = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            int x = nums[i];
            if (i >= x) {
                a.add(new int[]{x, i - x});
            }
        }
        return maxEnvelopes(a);
    }

    // 354. 俄罗斯套娃信封问题
    private int maxEnvelopes(List<int[]> envelopes) {
        //对位置排序,小的元素在前,大的元素在后
        envelopes.sort((a, b) -> {
            if (a[0] == b[0]) {
                return b[1] - a[1];
            }
            return a[0] - b[0];
        });

        List<Integer> g = new ArrayList<>();
        for (int[] e : envelopes) {
            int h = e[1];
            //最长增长序列模版思路:用二分在数组找对应的位置,然后更新元素值
            // 允许 LIS 相邻元素相等
            int j = upperBound(g, h); 
            if (j < g.size()) {
                g.set(j, h);
            } else {
                g.add(h);
            }
        }
        return g.size();
    }

    private int upperBound(List<Integer> g, int target) {
        int left = -1, right = g.size(); // 开区间 (left, right)
        while (left + 1 < right) { // 区间不为空
            // 循环不变量:
            // nums[right] > target
            // nums[left] <= target
            int mid = left + (right - left) / 2;
            if (g.get(mid) > target) {
                right = mid; // 范围缩小到 (left, mid)
            } else {
                left = mid; // 范围缩小到 (mid, right)
            }
        }
        return right;
    }
}
相关推荐
RD_daoyi1 小时前
Google偷偷给AI引用加了五个新功能:内联引用、悬停预览、品牌展示……但点击率真的回来了吗?
大数据·网络·人工智能·算法·安全·搜索引擎
船漏了就会沉1 小时前
后缀自动机(SAM):字符串处理的“万能瑞士军刀”
算法
白白白小纯2 小时前
算法篇—链表的中间节点
c语言·数据结构·算法·leetcode
Frostnova丶3 小时前
(19)LeetCode 54. 螺旋矩阵
算法·leetcode·矩阵
Frostnova丶3 小时前
(18)LeetCode 73. 矩阵置零
算法·leetcode·矩阵
冻柠檬飞冰走茶3 小时前
PTA基础编程题目集 7-11 分段计算居民水费(C语言实现)
c语言·开发语言·算法
得物技术3 小时前
推荐系统体验的数字化突破:得物自动化评测平台的技术实践|AICon 文章整理
算法·架构·llm
VALENIAN瓦伦尼安教学设备3 小时前
转子/行星/平行轴齿轮箱综合故障模拟实验台可复现常见机械问题
大数据·数据库·人工智能·嵌入式硬件·算法
rannn_1113 小时前
【力扣hot100】哈希表专题——从两数之和到最长连续序列
java·算法·leetcode·哈希