Leetcode问题:valid perfect square
我的回答是:
public class Solution {
public boolean isPerfectSquare(int num) {
int l = 0;
int r = (num>>1)+1;
while(l<=r) {
int mid = (l+r)>>1;
long temp = mid*mid;// why long
if( temp == num) return true;
else if( temp< num) l = mid+1;
else r=mid-1;
}
return false;
}
}
此回答时间限制超过(输入时2 ^ 31-1)。但如果我改变l,r,中长(不是int),它就有效。为什么? 的由于
答案 0 :(得分:2)
如果您调试您的代码,您可以看到出现了什么问题。一种方法来调试&#34;是插入print
语句,因此在temp
赋值后立即插入以下代码:
System.out.printf("l=%1$08x=%1$-10d r=%2$08x=%2$-10d mid=%3$08x=%3$-10d temp=%4$016x=%4$d%n", l, r, mid, temp);
if (temp < 0)
throw new IllegalStateException();
这将在十六进制和十进制中打印4个值l
,r
,mid
和temp
,对齐以便于比较。插入if
语句以在发生明显的内部错误时结束循环,并且它将触发。
致电isPerfectSquare(Integer.MAX_VALUE)
时的输出:
l=00000000=0 r=40000000=1073741824 mid=20000000=536870912 temp=0000000000000000=0
l=20000001=536870913 r=40000000=1073741824 mid=30000000=805306368 temp=0000000000000000=0
l=30000001=805306369 r=40000000=1073741824 mid=38000000=939524096 temp=0000000000000000=0
l=38000001=939524097 r=40000000=1073741824 mid=3c000000=1006632960 temp=0000000000000000=0
l=3c000001=1006632961 r=40000000=1073741824 mid=3e000000=1040187392 temp=0000000000000000=0
l=3e000001=1040187393 r=40000000=1073741824 mid=3f000000=1056964608 temp=0000000000000000=0
l=3f000001=1056964609 r=40000000=1073741824 mid=3f800000=1065353216 temp=0000000000000000=0
l=3f800001=1065353217 r=40000000=1073741824 mid=3fc00000=1069547520 temp=0000000000000000=0
l=3fc00001=1069547521 r=40000000=1073741824 mid=3fe00000=1071644672 temp=0000000000000000=0
l=3fe00001=1071644673 r=40000000=1073741824 mid=3ff00000=1072693248 temp=0000000000000000=0
l=3ff00001=1072693249 r=40000000=1073741824 mid=3ff80000=1073217536 temp=0000000000000000=0
l=3ff80001=1073217537 r=40000000=1073741824 mid=3ffc0000=1073479680 temp=0000000000000000=0
l=3ffc0001=1073479681 r=40000000=1073741824 mid=3ffe0000=1073610752 temp=0000000000000000=0
l=3ffe0001=1073610753 r=40000000=1073741824 mid=3fff0000=1073676288 temp=0000000000000000=0
l=3fff0001=1073676289 r=40000000=1073741824 mid=3fff8000=1073709056 temp=0000000040000000=1073741824
l=3fff8001=1073709057 r=40000000=1073741824 mid=3fffc000=1073725440 temp=0000000010000000=268435456
l=3fffc001=1073725441 r=40000000=1073741824 mid=3fffe000=1073733632 temp=0000000004000000=67108864
l=3fffe001=1073733633 r=40000000=1073741824 mid=3ffff000=1073737728 temp=0000000001000000=16777216
l=3ffff001=1073737729 r=40000000=1073741824 mid=3ffff800=1073739776 temp=0000000000400000=4194304
l=3ffff801=1073739777 r=40000000=1073741824 mid=3ffffc00=1073740800 temp=0000000000100000=1048576
l=3ffffc01=1073740801 r=40000000=1073741824 mid=3ffffe00=1073741312 temp=0000000000040000=262144
l=3ffffe01=1073741313 r=40000000=1073741824 mid=3fffff00=1073741568 temp=0000000000010000=65536
l=3fffff01=1073741569 r=40000000=1073741824 mid=3fffff80=1073741696 temp=0000000000004000=16384
l=3fffff81=1073741697 r=40000000=1073741824 mid=3fffffc0=1073741760 temp=0000000000001000=4096
l=3fffffc1=1073741761 r=40000000=1073741824 mid=3fffffe0=1073741792 temp=0000000000000400=1024
l=3fffffe1=1073741793 r=40000000=1073741824 mid=3ffffff0=1073741808 temp=0000000000000100=256
l=3ffffff1=1073741809 r=40000000=1073741824 mid=3ffffff8=1073741816 temp=0000000000000040=64
l=3ffffff9=1073741817 r=40000000=1073741824 mid=3ffffffc=1073741820 temp=0000000000000010=16
l=3ffffffd=1073741821 r=40000000=1073741824 mid=3ffffffe=1073741822 temp=0000000000000004=4
l=3fffffff=1073741823 r=40000000=1073741824 mid=3fffffff=1073741823 temp=ffffffff80000001=-2147483647
Exception in thread "main" java.lang.IllegalStateException
at Test.isPerfectSquare(Test.java:14)
at Test.main(Test.java:4)
如您所见,您的问题已在第一次迭代中发生,其中temp
计算为0
。
这是由平方0x2000_0000
时的数字溢出引起的。它应该是0x0400_0000_0000_0000
,但它是0
,因为乘法是使用int
数学完成的。
通过将至少一个数据转换为long
来更改为long
数学,例如将行更改为long temp = (long)mid * mid;
。
通过该更改,您的调试输出变为:
l=00000000=0 r=40000000=1073741824 mid=20000000=536870912 temp=0400000000000000=288230376151711744
l=00000000=0 r=1fffffff=536870911 mid=0fffffff=268435455 temp=00ffffffe0000001=72057593501057025
l=00000000=0 r=0ffffffe=268435454 mid=07ffffff=134217727 temp=003ffffff0000001=18014398241046529
l=00000000=0 r=07fffffe=134217726 mid=03ffffff=67108863 temp=000ffffff8000001=4503599493152769
l=00000000=0 r=03fffffe=67108862 mid=01ffffff=33554431 temp=0003fffffc000001=1125899839733761
l=00000000=0 r=01fffffe=33554430 mid=00ffffff=16777215 temp=0000fffffe000001=281474943156225
l=00000000=0 r=00fffffe=16777214 mid=007fffff=8388607 temp=00003fffff000001=70368727400449
l=00000000=0 r=007ffffe=8388606 mid=003fffff=4194303 temp=00000fffff800001=17592177655809
l=00000000=0 r=003ffffe=4194302 mid=001fffff=2097151 temp=000003ffffc00001=4398042316801
l=00000000=0 r=001ffffe=2097150 mid=000fffff=1048575 temp=000000ffffe00001=1099509530625
l=00000000=0 r=000ffffe=1048574 mid=0007ffff=524287 temp=0000003ffff00001=274876858369
l=00000000=0 r=0007fffe=524286 mid=0003ffff=262143 temp=0000000ffff80001=68718952449
l=00000000=0 r=0003fffe=262142 mid=0001ffff=131071 temp=00000003fffc0001=17179607041
l=00000000=0 r=0001fffe=131070 mid=0000ffff=65535 temp=00000000fffe0001=4294836225
l=00000000=0 r=0000fffe=65534 mid=00007fff=32767 temp=000000003fff0001=1073676289
l=00008000=32768 r=0000fffe=65534 mid=0000bfff=49151 temp=000000008ffe8001=2415820801
l=00008000=32768 r=0000bffe=49150 mid=00009fff=40959 temp=0000000063fec001=1677639681
l=0000a000=40960 r=0000bffe=49150 mid=0000afff=45055 temp=0000000078fea001=2029953025
l=0000b000=45056 r=0000bffe=49150 mid=0000b7ff=47103 temp=00000000843e9001=2218692609
l=0000b000=45056 r=0000b7fe=47102 mid=0000b3ff=46079 temp=000000007e8e9801=2123274241
l=0000b400=46080 r=0000b7fe=47102 mid=0000b5ff=46591 temp=0000000081629401=2170721281
l=0000b400=46080 r=0000b5fe=46590 mid=0000b4ff=46335 temp=000000007ff79601=2146932225
l=0000b500=46336 r=0000b5fe=46590 mid=0000b57f=46463 temp=0000000080acd501=2158810369
l=0000b500=46336 r=0000b57e=46462 mid=0000b53f=46399 temp=0000000080522581=2152867201
l=0000b500=46336 r=0000b53e=46398 mid=0000b51f=46367 temp=000000008024d9c1=2149898689
l=0000b500=46336 r=0000b51e=46366 mid=0000b50f=46351 temp=00000000800e36e1=2148415201
l=0000b500=46336 r=0000b50e=46350 mid=0000b507=46343 temp=000000008002e631=2147673649
l=0000b500=46336 r=0000b506=46342 mid=0000b503=46339 temp=000000007ffd3e09=2147302921
l=0000b504=46340 r=0000b506=46342 mid=0000b505=46341 temp=0000000080001219=2147488281
l=0000b504=46340 r=0000b504=46340 mid=0000b504=46340 temp=000000007ffea810=2147395600
false