---
# System prepended metadata

title: 2111. Minimum Operations to Make the Array K-Increasing
tags: [Leetcode, Longest Increasing Subsequence, Hard, Greedy]

---

# 2111. Minimum Operations to Make the Array K-Increasing
###### tags: `Leetcode` `Hard` `Greedy` `Longest Increasing Subsequence`
Link: https://leetcode.com/problems/minimum-operations-to-make-the-array-k-increasing/description/
## 思路
本质就是在每个k间隔的系列里找到最长递增子序列的长度，其余未被选定的元素只需要使之与相邻的元素相同即可, 这样这些未被选中的元素就对应着最少需要修改的数目

**followup**：如果要求构造所有元素为正、且严格的递增序列怎么办？这里会出现的一个问题是，找到LIS之后，其他元素的改动可能无法实现。比如[1,1,2]，最长严格递增序列是[1,2]，但是你无法只修改一个数字得到合法的解。方法是，将所有的元素都减去其下标(1,2,3...)，然后去除掉负数，在其中找LIS（更确切的说是非递减序列）。在这个例子中，变换后的数组是[0,-1,-1]。所以其LIS的长度其实只有1. 去掉负数的那些元素k无论如何都无法成为一个严格递增序列里面的成员，原因是它之前的元素个数太少，即使第一个元素从1开始以公差1递增，到该元素时也超过了k本身。
## Code
```java=
class Solution {
    public int kIncreasing(int[] arr, int k) {
        List<Integer> list = new ArrayList<>();
        int ans = 0;
        int n = arr.length;
        for(int i=k; i<2*k; i++){
            int idx = i-k;
            while(idx<n){
                list.add(arr[idx]);
                idx += k;
            }
            ans+=list.size()-LIS(list);
            list = new ArrayList();
        }
        return ans;
    }
    private int LIS(List<Integer> list){
        List<Integer> increasing = new ArrayList<>();
        for(int i=0; i<list.size(); i++){
            int num = list.get(i);
            if(increasing.size()==0 || increasing.get(increasing.size()-1)<=num){
                increasing.add(num);
            }
            else{
                int start = 0, end = increasing.size()-1;
                while(start<end){
                    int mid = start+(end-start)/2;
                    if(increasing.get(mid)<=num){
                        start = mid+1;
                    }
                    else end = mid;
                }
                increasing.set(start, num);
            }
        }
        return increasing.size();
    }
}
```