嵌入式实习笔面试第二弹

只能说配合chatgpt debug+学习代码真香!要好好利用chatgpt提升自己的项目完成能力和算法能力!


Leetcode 第四题

这道题我倒是有思路,思路非常简单粗暴,就是先合并数组,用sort排序后求解中位数。但是一直AC不了,现在附上我的代码和经过chatgpt改动的代码

我原来的代码:

#include<iostream>
#include<algorithm>
#include <vector>
using namespace std;
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = sizeof(nums1) / sizeof(nums1[0]);
        int m = sizeof(nums2) / sizeof(nums2[0]);
        for (int i = 0; i < m; i++) {
            nums1[n + i] = nums2[i];
        }
        int k = sizeof(nums1) / sizeof(nums1[0]);
        sort(nums1.begin(), nums1.begin()+ m + n);
        if (k % 2 != 0)
        {
            cout << nums1[k / 2 + 1] << endl;
        }
        else {
            cout << (nums1[k / 2] + nums1[k / 2 + 1]) / 2.0 << endl;
        }
        return 0;
    }
}

chatgpt评价这个代码的缺点:

我记得sizeof(num)/sizeof(num[0])的方式也可以用于计算数组长度,因此我把自己的疑问讲了出来,chatgpt回答如下:

也就是说不是vector不能使用sort,而是vector无法正确使用sizeof!

之后chatgpt给出了它改动后的代码:

#include<iostream>
#include<algorithm>
#include <vector>
using namespace std;
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        int n = nums1.size();
        int m = nums2.size();
        nums1.resize(n + m);
        for (int i = 0; i < m; i++) {
            nums1[n + i] = nums2[i];
        }
        int k = n + m;
        sort(nums1.begin(), nums1.end());
        if (k % 2 != 0)
        {
            return nums1[k / 2];
        }
        else {
            return (nums1[k / 2 - 1] + nums1[k / 2]) / 2.0;
        }//数组是从零开始!!!!
    }
};

这次就正常运行了

在正常运行之后,我害怕算法的时间复杂度不满足要求,所以也问了这个问题

可以看出我的算法并不完全符合题意(虽然并没有超时)

要如何使时间复杂度满足O(log(m+n))呢?我的想法是不用合并数组,直接寻找中位数。查找方面我们可以采用二分查找的算法。

此时时间复杂度O(log(min(n1, n2))),n1 和 n2 分别为两个数组的长度。空间复杂度为 O(1),因为算法只使用了常数级别的额外空间。

#include<algorithm>
using namespace std;
class Solution {
public:
    double findMedianSortedArrays(vector<int>& nums1, vector<int>& nums2) {
        const int n1 = nums1.size();
        const int n2 = nums2.size();
        if (n1 > n2) return findMedianSortedArrays(nums2, nums1);
        const int k = (n1 + n2 + 1) / 2;
        int left = 0;
        int right = n1;
        while (left < right) {
            const int m1 = left + (right - left) / 2;
            const int m2 = k - m1;
            if (nums1[m1] < nums2[m2 - 1])
                left = m1 + 1;
            else
                right = m1;
        }
        const int m1 = left;
        const int m2 = k - left;
        const int c1 = max(m1 <= 0 ? INT_MIN : nums1[m1 - 1],
            m2 <= 0 ? INT_MIN : nums2[m2 - 1]);
        if ((n1 + n2) % 2 == 1)
            return c1;
        const int c2 = min(m1 >= n1 ? INT_MAX : nums1[m1],
            m2 >= n2 ? INT_MAX : nums2[m2]);
        return (c1 + c2) * 0.5;
    }
};

具体来说,该算法的思路是将两个数组分别划分为两部分,使得左半部分的长度之和等于右半部分的长度之和,且左半部分的最大值不大于右半部分的最小值。这样,中位数就可以通过左半部分的最大值和右半部分的最小值计算得出。为了实现这个思路,算法使用了二分查找的方法。具体的步骤如下:

我一直不太明白INT_MIN和INT_MAX这样的量,所以我问了chatgpt。

这段代码使用了 INT_MIN 和 INT_MAX 这两个常量。它们是 C++ 标准库头文件 <limits.h> 或 <climits> 中定义的常量,分别表示 int 类型能够存储的最小值和最大值。

也就是

 const int c1 = max(m1 <= 0 ? INT_MIN : nums1[m1 - 1],
            m2 <= 0 ? INT_MIN : nums2[m2 - 1]);

这段代码,是在防止m1和m2小于0从而导致数组越界的情况,如果越界,则使用INT_MIN和INT_MAX这样的值。

我自己的算法:
将两个数组合并,然后排序求中位数,时间复杂度为O((m+n)log(m+n)),空间复杂度为O(m+n),相对而言时间和空间复杂度都较高。
符合题意的算法:
采用二分查找的思路,时间复杂度为O(log(min(m, n))),空间复杂度为O(1),可以看作是比较高效的算法。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值