leetcode刷题记录一

本文记录了LeetCode中的几道关于寻找缺失和重复正数的题目,包括41. 缺失的第一个正数、287. 寻找重复数和154. 寻找旋转排序数组中的最小值 II。文章提供了多种解题思路,如空间复杂度O(1)的解决方案和二分法,并分析了不同情况下的边界处理和时间复杂度。
摘要由CSDN通过智能技术生成

41. 缺失的第一个正数

给你一个未排序的整数数组,请你找出其中没有出现的最小的正整数。

题解

要求空间复杂度O(1)。前不久刚做了一道循环排列的题,所以看见“就地”两个字,秒懂: 将数字放到对应的位置上

有个特殊的样例,nums[i] - 1可能会超出int的范围

class Solution {
public:
    int firstMissingPositive(vector<int>& nums) {
        int n = nums.size();
        for (int i = 0; i < n; ++i) if (nums[i] >= 0) nums[i]--;

        for (int i = 0; i < n; ++i) {
            int pos = nums[i];
            while(pos >= 0 && pos < n && pos != nums[pos]) swap(pos, nums[pos]);
        }

        int ans = n + 1;
        for (int i = 0; i < n; ++i) if (nums[i] != i) {
            ans = i + 1;
            break;
        }
        return ans;
    }
};

287. 寻找重复数

给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数

题解一

要求空间复杂度O(1)、时间复杂度小于O( n 2 n^2 n2)、不能更改原数组。二分枚举答案,遍历整个数组,如果小于或者等于枚举的答案的个数大于枚举的答案,说明左半段出现了重复,否则,说明右半段出现了重复。

妙啊!原味:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/er-fen-fa-si-lu-ji-dai-ma-python-by-liweiwei1419/

class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int n = nums.size();
        int l = 1, r = n;
		
        // 时间换空间,有点儿意思
        while(l < r) {
            int mid = (l + r) >> 1;      // 枚举答案

            int cnt = 0;
            for (int num: nums) if (num <= mid) cnt++;

            if (cnt > mid) r = mid;
            else  l = mid + 1;
        }

        return l;
    }
};

题解二

oooooorz,还可以用二进制考虑。思想就一句话:如果一个数是重复的,那么对应的二进制位中1的个数肯定比原来多,因为重复了嘛。

详细讲解:https://leetcode-cn.com/problems/find-the-duplicate-number/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by–52/

// beautiful code
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int n = nums.size();
        int ans = 0;
        for (int i = 0; i < 32; ++i) {
            int a = 0, b = 0;
            int mask = 1 << i;
            for (int j = 0; j < n; ++j) {
                if (nums[j] & mask) a++;
                if (j & mask) b++;
            }
            if (a > b) ans += mask;  // ans = ans | mask;  is ok!
        }
        return ans;
    }
};
// sad code
class Solution {
public:
    int findDuplicate(vector<int>& nums) {
        int n = nums.size();

        int bit_cnt[40];
        memset(bit_cnt, 0, sizeof(bit_cnt));

        for (int num: nums) {
            int t = 0;
            while(num) bit_cnt[t++] += (num & 1), num >>= 1;
        }

        int bit_tot[40];
        memset(bit_tot, 0, sizeof(bit_tot));

        for (int i = 1; i < n; ++i) {
            int t = 0, num = i;
            while(num) bit_tot[t++] += (num & 1), num >>= 1;
        }

        int ans = 0;
        for (int i = 0; i < 32; ++i) if (bit_tot[i] < bit_cnt[i]) ans += (1 << i);
        return ans;
    }
};

题解三

n + 1 n + 1 n+1

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值