231. 2的幂
2^3=8 得 8是2的幂
判断一个整数是不是2的幂,可根据二进制来分析。2的幂如2,4,8,等有一个特点:
二进制数首位为1,其他位为0,如2为10,4为100
2&(2-1)=0 4&(4-1)=0 即得出结论如果一个数n为2的幂,则n(n-1)=0
258 各位相加的过程为:3 + 8 = 11
, 1 + 1 = 2
。 由于 2
是一位数,所以返回 2。
有如下关系:num = a * 10000 + b * 1000 + c * 100 + d * 10 + e
即:num = (a + b + c + d + e) + (a * 9999 + b * 999 + c * 99 + d * 9)
因为 a * 9999 + b * 999 + c * 99 + d * 9 一定可以被9整除,因此num模除9的结果与 a + b + c + d + e 模除9的结果是一样的。
对数字 a + b + c + d + e 反复执行同类操作,最后的结果就是一个 1-9 的数字加上一串数字,最左边的数字是 1-9 之间的,右侧的数字永远都是可以被9整除的。
return 1 + (num-1) % 9;
371.两整数之和 不使用+.-符号
思路:使用异或运算,可以计算出两个数中仅有1的位置相加 a^b
使用与运算,可以知道两个数都为1的位置,需要进位。a&b
将以上两个结果相加,就是想要的结果。但是仍然不能使用+,则循环执行上面两部,直到b为0,则不需要相加,退出。
while(b!=0){
c = a^b;
b = (a&b)<<1;
a = c;
}
return a;
342.4的幂
先判断n是不是2的幂,因为4的幂一定是2的幂 n&(n-1)==0
因为如果是4的幂,则二进制1后面的0为偶数个,也就是1一定在奇数上。通过n与.0X55555555(....1010101)进行&操作,保留奇数位,判断是否改变。(num&0x55555555)==num
最后结果 return (num&0x55555555)==num && (num&0x55555555)==num
326.3的幂
要求n是不是3的幂,则log3(n)==0即可。 logm(n) = log10(n)/log10(m);
double result = log10(n)/log10(3);
return (result==int(result))?true:false;
453. 最小移动次数使数组元素相等
题:给定一个长度为 n 的非空整数数组,找到让数组所有元素相等的最小移动次数。每次移动可以使 n - 1 个元素增加 1。
例子: 输入:[1,2,3] 输出: 3
解释: 只需要3次移动(注意每次移动会增加两个元素的值):[1,2,3] => [2,3,3] => [3,4,3] => [4,4,4]
思路:逆向思考,每次移动让剩余的n-1个数加1,相当于每次移动让选定的那个数减1, 所以最少移动次数其实就是所有元素减去最小元素的和
代码:public int minMoves(int[] nums) {
int min = nums[0];
int sum = nums[0];
for(int i=1;i<nums.length;i++){
sum +=nums[i];
if(nums[i]<min){
min = nums[i];
}
}
return sum-min*nums.length;
}
题:给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。
找到所有在 [1, n] 范围之间没有出现在数组中的数字。
例:输入:[4,3,2,7,8,2,3,1] 输出:[5,6]
思路:将数字中的数字nums[i]对应的索引中的数(比如:第一个数nums[0]是4,则对用的4的索引的数nums[4-1]=7)变为负数,即nums[4-1]=-7。
数组遍历完一遍之后,变为 [-4,-3,-2,-7,8
,2
,-3,-1],对用的index为5,6。即未找到的数为5,6
例:输入16,输出True 输入14,输出False
思路:1,首先想到的是暴力法或者二分查找等方法,从1~n中找一个数m,不断判断m*m==n?
2,通过列举所有的完全平方数,1,4,9,16,25,36,49,64,81,100…等等,发现完全平方数的差都为奇数,即1,3,5,7,9,11,13,15…等等~所以可以判断完全平方数应该是N个奇数的和。
核心代码:for(int i = 1; num > 0; i += 2){
num -= i;
}
return num == 0;