代码随想录Day2-数组-二分查找&移除元素:力扣69、367、27题

69. x的平方根

题目链接

方法一:遍历

思路

逐个遍历判断

  • 时间复杂度: O ( n ) O(\sqrt n) O(n )
  • 空间复杂度: O ( 1 ) O(1) O(1)
C++代码
class Solution {
public:
    int mySqrt(int x) {
        for (long i = 0; i <= x; ++i) {
            if (i * i == x) {
                return i;
            } if (i * i > x) {
                return i - 1;
            }
        }
        return 0;
    }
};

方法二:二分查找

思路

二分查找,左闭右闭,查找不到返回右边界值。

  • 时间复杂度: O ( log ⁡ n ) O(\log n) O(logn)
  • 空间复杂度: O ( 1 ) O(1) O(1)
C++代码
class Solution {
public:
    int mySqrt(int x) {
        int left = 0;
        int right = x;

        while (left <= right) {
            long long mid = (right - left) / 2 + left;
            if (mid * mid == x) {
                return mid;
            } else if (mid * mid < x) {
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return right;
    }
};

367. 有效的完全平方数

题目链接

方法一:遍历

思路

逐个遍历判断

  • 时间复杂度: O ( n ) O(\sqrt n) O(n )
  • 空间复杂度: O ( 1 ) O(1) O(1)
C++代码
class Solution {
public:
    bool isPerfectSquare(int num) {
        for (long long i = 1; i <= num; ++i) {
            if (i * i == num) return true;
            if (i * i > num) return false;
        }
        return false;
    }
};

方法二:二分查找

思路

二分查找,左闭右闭,查找不到返回false。

  • 时间复杂度: O ( log ⁡ n ) O(\log n) O(logn)
  • 空间复杂度: O ( 1 ) O(1) O(1)
C++代码
class Solution {
public:
    bool isPerfectSquare(int num) {
        int left = 0;
        int right = num;

        while (left <= right) {
            long long mid = (right + left) / 2;
            if (mid * mid == num) return true;
            else if (mid * mid < num) left = mid + 1;
            else right = mid - 1;
        }
        return false;
    }
};

看完讲解的思考

代码实现遇到的问题

没有注意到数值取值范围的问题

  • short:2字节,共2*8=16bit, − 2 15 ∼ 2 15 − 1 -2^{15} \sim 2^{15}-1 2152151
  • int:4字节, − 2 31 ∼ 2 31 − 1 -2^{31} \sim 2^{31}-1 2312311
  • long:Windows和32位Linux上是4字节,64位Linux上是8字节, − 2 31 ∼ 2 31 − 1 -2^{31} \sim 2^{31}-1 2312311 − 2 63 ∼ 2 63 − 1 -2^{63} \sim 2^{63}-1 2632631
  • long long:8字节, − 2 63 ∼ 2 63 − 1 -2^{63} \sim 2^{63}-1 2632631

27. 移除元素

题目链接
代码随想录文章讲解链接

方法一:快慢双指针

思路

设置两个指针索引,一个快指针fast一个慢指针slowfast负责检测元素是否需要被移除,slow负责保留不用移除的元素。
nums[fast] == val时,元素不用保留,fast直接往后走;
nums[fast] != val时,元素需要保留,将nums[fast]nums[slow]替换位置,slow当前位置已是需要保留的元素,所以slow往后移一步,由于fast走的比slow快,所以替换给fast的元素一定是fast检测过且不需要的,所以fast也往后移一步。
直到fast达到数组边界,所有元素检测完毕,且将要保留的元素移到了数组左端。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)
C++代码
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int slow = 0;
        int fast = 0;
        int size = nums.size();

        while (fast < size) {
            if (nums[fast] == val) {
                ++fast;
            } else {
                swap(nums[slow++], nums[fast++]);
            }
        }
        return slow;
    }
};

方法二:左右双指针

思路

设置左指针left和右指针right,此时left的作用相当于方法一的slowright的作用相当于方法一的fast,基本思想都差不多。
左右双指针的好处时不用重复移动要移除的元素,当要移除的元素在数组开头时,例如[1,2,3,4]要移除1,方法一的话需要不断移动1的位置。直到1到达最右端,而方法二可以直接移动到最右端而不用多次移动。

  • 时间复杂度: O ( n ) O(n) O(n)
  • 空间复杂度: O ( 1 ) O(1) O(1)
C++代码
class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int left = 0;
        int right = nums.size() - 1;

        while (left <= right) {
            if (nums[left] == val) {
                swap(nums[left], nums[right--]);
            } else {
                ++left;
            }
        }
        return left;
    }
};

看完讲解的思考

对于为啥方法二比方法一好没有想到,看了题解才发现。

代码实现遇到的问题

快慢指针的移动方式一开始没有理清楚。


最后的碎碎念

刚开始的题目还是简单些,不过刷题的效率有点低,老是不专注,支楞起来啊bro!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值