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

题目

给你一个整数数组 nums。

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

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

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

示例 1:

输入: nums = 0,2,1

输出: 2

解释:

  • 删除 nums[1] = 2。数组变为 [0, 1]。
  • 现在,nums[0] = 0 且 nums[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;
    }
}
相关推荐
UIU11434 分钟前
递归算法与汉诺塔
c++·学习·算法·c#·递归
用户979984807186 小时前
200 行代码写一个能跑的 AI Agent:不依赖任何框架,只靠 tool-calling 原理
算法
threerocks6 小时前
【Muse实战】X 流量作战室搭建保姆级教程 - 拥有你自己的运营团队
算法
GreenTea6 小时前
深度拆解 ScienceBuddy:如何用“双层递归自进化”构建高可靠科研 Agent Harness
前端·后端·算法
花椒技术6 小时前
2.46 秒生成 5 秒视频:拆解 H3 Max 的模型、推理栈与硬件协同
算法·音视频开发·视频编码
vivo互联网技术6 小时前
ART:妆容迁移框架,重新定义高保真妆容迁移 | ECCV 2026
人工智能·算法·图像识别
用户0441440924496 小时前
卫星信号模拟器里的四个坐标转换公式
算法
橘和柠6 小时前
阿里 open-code-review (AI代码审查工具)实战:安装、四层规则链、自定义规则格式与实测避坑
算法·面试
得物技术6 小时前
别再只卷向量检索了,得物交易搜索如何用“生成式”实现召回范式跃迁?
人工智能·算法·llm
罗西的思考6 小时前
[Agent Memory / 强化学习] MemPO源码学习笔记 ---(4)--- Rollout实现细节
人工智能·算法