【无标题】

21.最长递增子序列问题与扩展

300. 最长递增子序列

已解答

中等

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列 是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7]

子序列

示例 1:

输入:nums = [10,9,2,5,3,7,101,18]
输出:4
解释:最长递增子序列是 [2,3,7,101],因此长度为 4 。
static int l,r,mid;
    static int [] arr = new int[2500];
    public static int lengthOfLIS(int[] nums) {
        int n = nums.length;
        int length = 0;
        Arrays.fill(arr,2500);
        arr[0] = nums[0];
        for (int i = 1;i<n;i++){
            if (nums[i]>arr[length]){
                //如果能更新子序列长度数组
                arr[++length] = nums[i];
            }else{
                //
                l = 0;
                r = length;
                int ans = 0;
                while(l<=r){
                    mid = l+((r-l)>>1);
                    if (nums[i]>arr[mid]){
                        l = mid+1;
                    }else{
                        ans = mid;
                        r = mid-1;
                    }
                }
//                if(nums[i]<arr[ans]){
                    arr[ans] = nums[i];
//                }
            }
        }
        return length+1;
    }

2111. 使数组 K 递增的最少操作次数

已解答

困难

提示

给你一个下标从 0 开始包含 n 个正整数的数组 arr ,和一个正整数 k

如果对于每个满足 k <= i <= n-1 的下标 i ,都有 arr[i-k] <= arr[i] ,那么我们称 arrK 递增 的。

  • 比方说,

    arr = [4, 1, 5, 2, 6, 2]

    对于

    k = 2

    是 K 递增的,因为:

    • arr[0] <= arr[2] (4 <= 5)

    • arr[1] <= arr[3] (1 <= 2)

    • arr[2] <= arr[4] (5 <= 6)

    • arr[3] <= arr[5] (2 <= 2)

  • 但是,相同的数组 arr 对于 k = 1 不是 K 递增的(因为 arr[0] > arr[1]),对于 k = 3 也不是 K 递增的(因为 arr[0] > arr[3] )。

每一次 操作 中,你可以选择一个下标 i 并将 arr[i] 改成任意 正整数。

请你返回对于给定的 k ,使数组变成 K 递增的 最少操作次数

示例 1:

输入:arr = [5,4,3,2,1], k = 1
输出:4
解释:
对于 k = 1 ,数组最终必须变成非递减的。
可行的 K 递增结果数组为 [5,6,7,8,9],[1,1,1,1,1],[2,2,3,4,4] 。它们都需要 4 次操作。
次优解是将数组变成比方说 [6,7,8,9,10] ,因为需要 5 次操作。
显然我们无法使用少于 4 次操作将数组变成 K 递增的。
static int [] arr1 = new int[100000];
public static int kIncreasing(int[] arr, int k) {
    int n = arr.length;
    int count = 0;
    int length ;
    for (int i = 0;i<k;i++){
        length = (n-i+k-1)/k;
        int s = lengthOfLIS(arr,i,k);
        count=count+length-s;
    }
    return count;
}
static int l,r,mid;
public static int lengthOfLIS(int[] nums,int start,int k) {
    int n = nums.length;
    int length = 0;
​
    arr1[0] = nums[start];
    for (int i = start+k;i<n;i=i+k){
        if (nums[i]>=arr1[length]){
            //如果能更新子序列长度数组
            arr1[++length] = nums[i];
        }else{
            //
             l = 0;
             r = length;
            int ans = 0;
            while(l<=r){
                 mid = l+((r-l)>>1);
                if (nums[i]>=arr1[mid]){
                    l = mid+1;
                }else{
                    ans = mid;
                    r = mid-1;
                }
            }
            arr1[ans] = nums[i];
        }
    }
    return length+1;
}

646. 最长数对链

已解答

中等

相关标签

相关企业

给你一个由 n 个数对组成的数对数组 pairs ,其中 pairs[i] = [lefti, righti]lefti < righti

现在,我们定义一种 跟随 关系,当且仅当 b < c 时,数对 p2 = [c, d] 才可以跟在 p1 = [a, b] 后面。我们用这种形式来构造 数对链

找出并返回能够形成的 最长数对链的长度

你不需要用到所有的数对,你可以以任何顺序选择其中的一些数对来构造。

示例 1:

输入:pairs = [[1,2], [2,3], [3,4]]
输出:2
解释:最长的数对链是 [1,2] -> [3,4] 。
static int [] arr  = new int[1000];
public static int findLongestChain(int[][] pairs) {
    int n = pairs.length;
    //按第一个元素从小到大排序
    Arrays.sort(pairs, new Comparator<int[]>() {
        @Override
        public int compare(int[] o1, int[] o2) {
            return o1[0]-o2[0];
        }
    });
    arr[0] = pairs[0][1];
    int lenngth = 1;
    int r;
    int l;
    int mid;
    int [] cur;
    int ans = 0;
    for (int i = 1;i<n;i++){
        cur = pairs[i];
        if (cur[0]>arr[lenngth-1]){
            arr[lenngth++] = cur[1];
            continue;
        }
        r = lenngth-1;
        l = 0;
        while (l<=r){
            mid = l+((r-l)>>1);
            if (cur[0]>arr[mid]){
                l = mid+1;
            }else{
                ans = mid;
                r = mid-1;
            }
        }
        if (cur[1]<arr[ans]){
            arr[ans] = cur[1];
        }
    }
    return lenngth;
}

354. 俄罗斯套娃信封问题

已解答

困难

相关标签

相关企业

给你一个二维整数数组 envelopes ,其中 envelopes[i] = [wi, hi] ,表示第 i 个信封的宽度和高度。

当另一个信封的宽度和高度都比这个信封大的时候,这个信封就可以放进另一个信封里,如同俄罗斯套娃一样。

请计算 最多能有多少个 信封能组成一组“俄罗斯套娃”信封(即可以把一个信封放到另一个信封里面)。

注意:不允许旋转信封。

示例 1:

输入:envelopes = [[5,4],[6,4],[6,7],[2,3]]
输出:3
解释:最多信封的个数为 3, 组合为: [2,3] => [5,4] => [6,7]。
static int r,l,mid;
public static int maxEnvelopes(int[][] envelopes) {
    //先按高度进行排序,因为会出先高度一样的情况,高度一样就按宽度从大到小排序,因为小的后面会会更新大的值,
    // 如果大的放后面,小的就会被更新,就可以转换为最长递增子序列问题了
    Arrays.sort(envelopes, new Comparator<int[]>() {
        @Override
        public int compare(int[] o1, int[] o2) {
           return o1[1] - o2[1]==0 ? o2[0] - o1[0]:o1[1] - o2[1];
        }
    });
    int [] ends = new int[envelopes.length];
    int length = 1;
    ends[0] = envelopes[0][0];
    for (int i = 1;i<envelopes.length;i++){
        if (envelopes[i][0]>ends[length-1]){
            ends[length++] = envelopes[i][0];
            continue;
        }else {
            int ans = 0;
            l = 0;
            r = length-1;
            while (l<=r){
                mid = l+((r-l)>>1);
                if (envelopes[i][0]>ends[mid]){
                    l = mid+1;
                }else{
                    ans = mid;
                    r = mid-1;
                }
            }
            ends[ans] = envelopes[i][0];
        }
    }
    return length;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值