数组练习1

 56.合并区间

class Solution {
    public int[][] merge(int[][] intervals) {
        // 先按照区间的左端点进行排序
        Arrays.sort(intervals, (a,b)->a[0]-b[0]);
        List<int[]> ans = new ArrayList<>();
        // 遍历每个区间
        for(int[] inter : intervals){
            int m = ans.size();
            // 区间合并的情况,ans中有区间,且最后一个区间的右端点值>=当前区间的左端点值
            if(m>0 && inter[0] <= ans.get(m-1)[1]){
                // 更新右端点值
                ans.get(m-1)[1] = Math.max(ans.get(m-1)[1],inter[1]);
            }else{
                // 加入新的区间,不需要合并
                ans.add(inter);
            }
        }
        return ans.toArray(new int[ans.size()][2]);
    }
}

41.缺失的第一个正数

注意:题干要去空间复杂度为常数,因此我们可以借助原本的数组。

实际上,对于一个长度为 N 的数组,其中没有出现的最小正整数只能在 [1,N+1] 中。因为如果 [1,N] 都出现了,那么答案是 N+1,否则答案是 [1,N]中没有出现的最小正整数。

要么采用打标记的方式,要么采用置换的方法。这里我采用的是通过置换将数组恢复成[1, 2, ..., N] 的形式,但其中有若干个位置上的数是错误的,每一个错误的位置就代表了一个缺失的正数。

步骤:对数组进行一次遍历,对于遍历到的数 x=nums[i],如果 x∈[1,N],交换 nums[i]和 nums[x−1],这样 x 就出现在了正确的位置。在完成交换后,新的 nums[i]\ 可能还在[1,N] 的范围内,需要继续进行交换操作,直到 x∉[1,N]。

注意到上面的方法可能会陷入死循环。如果 nums[i]恰好与 nums[x−1] 相等,那么就会无限交换下去。因此出现这种情况,我们可以跳出循环,开始遍历下一个数。

由于每次的交换操作都会使得某一个数交换到正确的位置,因此交换的次数最多为 N,整个方法的时间复杂度为 O(N)。

class Solution {
    public int firstMissingPositive(int[] nums) {
        int n = nums.length;
        // 恢复数组
        for(int i=0; i<n; i++){
            while(nums[i]>0 && nums[i]<=n && nums[nums[i]-1] != nums[i]){
                int temp = nums[nums[i]-1];
                nums[nums[i]-1] = nums[i];
                nums[i] = temp;
            }
        }
        // 找到第一个错误的位置
        for(int i=0; i<n; i++){
            if(nums[i] != i+1){
                return i+1;
            }
        }
        return n+1;

    }
}

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值