1. 不使用变量交换两个数
# 异或
a ^ b = c
c ^ b = a
a ^ c = b
numbers[0] ^= numbers[1];
numbers[1] ^= numbers[0];
numbers[0] ^= numbers[1];
# 加减
A = A+B
B = A-B
A = A-B
numbers[1]=numbers[0]+numbers[1];
numbers[0]=numbers[1]-numbers[0];
numbers[1]=numbers[1]-numbers[0];
2.位运算巧妙题解
(此题解利用了异或的性质)
def singleNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
res = 0
for i in nums:
res^=i
return res
(此题解跳出了题目本身,可以推广到在多个重复n次的数字中找到唯一出现一次的数)
int singleNumber(vector<int>& nums) {
int value=0;
for(int i=0;i<32;i++)
{
int sum=0;
for(int j=0;j<nums.size();j++)
{
if((nums[j]>>i)&1)
{
sum+=1;
}
}
value+=((sum%3)<<i);
}
return value;
}
(此题解的核心在于分组,因为相同元素,在所有bit位是一致的,而不同的数字,必然有某一个bit位存在差异,而找到所有值异或结果后(即可获取存在差异的bit位位置),只需根据存在差异的那一个bit位,将两个不同的数字分到不同的组,即可求出结果。)
vector<int> singleNumber(vector<int>& nums) {
vector<int> t(2,0);
int value_xor=nums[0]^nums[1];
for(int i=2;i<nums.size();i++)
{
value_xor^=nums[i];
}
int index=0;
for(int i=0;i<32;i++)
{
if((value_xor>>i)&1)
{
index=i;
break;
}
}
for(int i=0;i<nums.size();i++)
{
if((nums[i]>>index)&1)
{
t[0]^=nums[i];
}
else
{
t[1]^=nums[i];
}
}
return t;
}
3.求最大值
int(((a+b)+abs(a-b))/2)
4.快速幂
原理如下:
def myPow(self, x, n):
"""
:type x: float
:type n: int
:rtype: float
"""
if x==0:
return 0
res = 1
if n<0:
x,n = 1/x,-n
#x=3,n=6
#n=6(0x110),res=1,x=3*3 -> n=3,x=9
# n=3(0x11),res=9,x=9*9 -> n=1,x=81
# n=1(0x1),res=729,x=81*81 -> n=0,x=6561
while n>0:
if n&1==1:
res*=x
x*=x
n/=2
return res
暴力遍历:
class Solution:
def findEvenNumbers(self, digits: List[int]) -> List[int]:
ret = set()
L = len(digits)
for i in range(L):
if digits[i] == 0:
continue
for j in range(L):
for k in range(L):
t = digits[i]*100+digits[j]*10+digits[k]
if i!=j and i!=k and j!=k and t%2==0:
ret.add(t)
return sorted(list(ret))
偶数顺序遍历:
class Solution:
def findEvenNumbers(self, digits: List[int]) -> List[int]:
dict_ = {}
ret = []
for i in digits:
dict_[i] = dict_.get(i,0)+1
for i in range(100,999,2):
t = 0
t_ = {}
flag = True
j = i
while j>0:
t = j%10
t_[t] = t_.get(t,0)+1
if t_[t]>dict_.get(t,0):
flag = False
break
j//=10
if flag:
ret.append(i)
return ret
证明结论:每次向后增加一位时, 我们只考虑前面的余数部分, 这样是不会影响结果的。
class Solution:
def divisibilityArray(self, word: str, m: int) -> List[int]:
ans, x = [], 0
for d in map(int, word):
x = (x * 10 + d) % m
ans.append(int(x == 0))
return ans