• 1671 得到山行数组的最少删除次数(贪心+二分)


    题目

    1671
    我们定义 arr 是 山形数组 当且仅当它满足:

    arr.length >= 3
    存在某个下标 i (从 0 开始) 满足 0 < i < arr.length - 1 且:
    arr[0] < arr[1] < … < arr[i - 1] < arr[i]
    arr[i] > arr[i + 1] > … > arr[arr.length - 1]
    给你整数数组 nums​ ,请你返回将 nums 变成 山形状数组 的​ 最少 删除次数。

    示例 1:

    输入:nums = [1,3,1]
    输出:0
    解释:数组本身就是山形数组,所以我们不需要删除任何元素。
    示例 2:

    输入:nums = [2,1,1,5,6,2,3,1]
    输出:3
    解释:一种方法是将下标为 0,1 和 5 的元素删除,剩余元素为 [1,5,6,3,1] ,是山形数组。

    提示:

    3 <= nums.length <= 1000
    1 <= nums[i] <= 109
    题目保证 nums 删除一些元素后一定能得到山形数组。

    题解

    class Solution {
        public int minimumMountainRemovals(int[] nums) {
            //依次从前往后,从后往前寻找最长的,在相加更新最大值
            int[] l = longestObstacleCourseAtEachPosition(nums);
            int[] r = longestObstacleCourseAtEachPosition(reverse(nums));
            r = reverse(r);
            int max_cur = 0;
            int n = nums.length;
            for (int i = 0; i < n; i++) {
                if (l[i] + r[i] > max_cur && l[i] >= 2 && r[i] >= 2) {
                    max_cur = l[i] + r[i];
                }
            }
            return n - max_cur + 1;
        }
    
        public int[] longestObstacleCourseAtEachPosition(int[] obstacles) {
            List<Integer> g = new ArrayList<>();
            int n = obstacles.length, index = 0;
            int[] ans = new int[n];
            for (int x : obstacles) {
                int j = lowerBound(g, x);
                if (j == g.size()) {
                    g.add(x);
                } else {
                    g.set(j, x);
                }
                ans[index++] = j + 1;
            }
            return ans;
        }
    
        //返回大于等于target的第一个下标
        public int lowerBound(List<Integer> g, int target) {
            int left = 0, right = g.size() - 1;
            while (left <= right) {
                int mid = (right - left) / 2 + left;
                if (g.get(mid) < target) {
                    left = mid + 1;
                } else {
                    right = mid - 1;
                }
            }
            return left;
        }
    
        //倒置数组
        public int[] reverse(int[] nums) {
            int n = nums.length;
            int[] newArray = new int[n];
            for (int i = 0; i <= n >> 1; i++) {
                newArray[i] = nums[n - i - 1];
                newArray[n - i - 1] = nums[i];
            }
            return newArray;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
  • 相关阅读:
    读取一张图片各种颜色占比
    Hadoop入门(四):SSH免密登录 配置
    好心情:双相情感障碍会影响记忆力吗
    没错,请求DNS服务器还可以使用UDP协议
    Unity 顶点vertices,uv,与图片贴图,与mesh
    git 的 版本问题,以及idea中使用 git版本回滚操作,以及git版本和idea代码历史记录的区别
    2023年Java面试题及答案整理
    设计模式_单例模式(C++)
    2023年09月 C/C++(二级)真题解析#中国电子学会#全国青少年软件编程等级考试
    中国居民身份证号码校验算法
  • 原文地址:https://blog.csdn.net/fffffall/article/details/133875987