二分法-数据类型定义导致的内存超限

力扣心得1 整数溢出导致的内存超限 —Q-69.x 的平方根

1、问题描述:一直显示【内存超限】


博主在学习二分法,做力扣69. x 的平方根这一题的时候,遇到一个内存超限的问题,抓耳挠腮了好久,都没有找到原因在哪:
在这里插入图片描述

题目要求不使用 pow(x, 0.5) 或者 x ** 0.5等自带功能,求出一个非负整数的算术平方根。使用二分法的思想本身倒是很简单,通过左右两个指针不断去接近其算术平方根即可
在检查了几遍自己大体思路没问题后,我开始针对这个测试案例进行思考,最终发现了问题~

先上干货,debug后的正确代码:

class Solution {
    public int mySqrt(int x) {
        int left=0;
        int right=x;
        int res=-1;
        while(left<=right){
            int mid=(left+right)/2;
            if((long)mid*mid>x){//在判断条件中,中间指针mid前加上(long),避免mid^2超出int类型上限
                right=mid-1;
            }else if(mid*mid<=x){
                res=mid;
                left=mid+1;
            }
        }
        return res;
    }
}

2、原因与解决办法

我对测试案例进行观察,发现2147395599这个数字好像比较特别,好像是int类型数组的上限也是2147开头的数字,于是去查询了一下:
在这里插入图片描述
这里我就发现似乎找到了问题所在了 ,于是写了个脚本测试了一下,到底mid是在哪个地方出问题了:

public static void main(String[] args) {
        int a1 = 46341;
        int square1 = a1 * a1;
        int a2 = 46340;
        int square2 = a2 * a2;
        System.out.println(square1);
        System.out.println(square2);
}

输出:

-2147479015//square1  实际46341^2=2147488281
2147395600//square2

这里由于square被定义为int类型,因此出现了整数溢出,应该输出输出为2147488281的结果,最后变成了:-2147479015。而本题报错的测试用例2147395599处于2147395600~2147488281

超限过程

下面我们快来看一下这个内存超限的过程:
我们可以看一下第一次进入这个while循环的时候,mid就变成了107369780,这时候整型溢出就已经开始了,实际上107369780^2>>x,然而却因为整型溢出,被赋值成负数,从而错误的执行
else if(mid*mid<=x)这条语句,将left指针变成107369781。
在这里插入图片描述
但是如果仅仅是一直进入这个循环,只是left一直往右移动,顶多只是计算结果错误,还不至于内存超限
坏就坏在mid往右移动的时候,有的计算结果在内存超限后,不光会错误地把mid*mid的结果变成-2147479015这样的负数,还会因为溢出变成一些错误的正数,因此,还可能会进入if(mid*mid>x)这个循环,所以,leftright指针会像在上图中这样反复横跳,从而导致内存超限。

博主用编译器打印了一下,样最后leftright会在哪两个值上一直反复横跳,这是最后输出的结果:

mid			-715915930
left		-715915929
mid			715739835
left		715739836
mid			-715915930
left		-715915929
mid			715739835
left		715739836
mid			-715915930
left		-715915929

结果显示,mid最终在-715915930715739835之间反复横跳,导致内存超限

最后,在判断前加个long定义一下数据类型就可以了~

这是个小问题,希望大家有则改之,无则加勉,永远都不会受到bug困扰,我们下期再见!

相关推荐

  1. ClickHouse中“大列”造成JOIN内存问题

    2024-06-17 14:10:01       46 阅读
  2. 【ES】--Elasticsearch深度分页/内存等问题

    2024-06-17 14:10:01       60 阅读
  3. 解决方案:应对文本数据处理有效策略

    2024-06-17 14:10:01       37 阅读
  4. Redis数据类型内部实现

    2024-06-17 14:10:01       48 阅读
  5. EasyExcel导入导出数据类型转换

    2024-06-17 14:10:01       23 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-06-17 14:10:01       98 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-06-17 14:10:01       106 阅读
  3. 在Django里面运行非项目文件

    2024-06-17 14:10:01       87 阅读
  4. Python语言-面向对象

    2024-06-17 14:10:01       96 阅读

热门阅读

  1. HIVE及SparkSQL优化经验

    2024-06-17 14:10:01       35 阅读
  2. Docker Desktop Installer For Windows 国内下载地址

    2024-06-17 14:10:01       57 阅读
  3. VB.net调用VC DLL(二)

    2024-06-17 14:10:01       32 阅读
  4. 教学资源共享平台的设计

    2024-06-17 14:10:01       34 阅读
  5. 【C语言】进程间通信之管道pipe

    2024-06-17 14:10:01       36 阅读