位运算
-
【136】只出现一次的数字:异或和
-
【offer 56】数组中数字出现的次数:全部异或一次,得到一个非零数为答案两数的异或值,取lowbit
-
将所有数根据lowbit与上面是否相同分成两组,答案一定分到了两边
-
两组的异或和分别就是这两个数,其他数都两两抵消了
-
lowbit:n&-n
去除最后一位数:n&(n-1)
数学规律
-
【6】N 字形变换:枚举每一行,每一列k
- 第一个数是
i+k*(2*numRows-2),第二个数是2*numRows-2-i+k*(2*numRows-2)
- 第一个数是
-
【31】下一个排列:给一个整数,输出下一个更大的全排列
-
思路:
-
最小的排列:12345升序,最大的排列:54321降序
-
更大:从前向后比较,字典序
-
最小的更大:
-
与原来相比,只有很靠后的一个数变大,例如:1243->1324
- 也就是用后面更大的数字,替换前面的
-
从后往前找到第一个小于后一个数的位置,然后从后面找到大于这个数的最小的数,与之交换
-
这一位变大后,剩下的尽可能最小,也就是升序,最后把后面的逆序即可
-
-
-
-
同【556】下一个更大元素 III,加一步范围判断
-
-
【60】排列序列:全排列第n小的数
- 每次选当前数时,每进一位右边相当于n!个数,拿总数减去就知道当前数是第几大的了,注意第0大就是逆序
-
【343】整数拆分:整除拆分为一些列数的乘积最大,同【offer 14】剪绳子
- 当n>=5 时,3*(n-3)>n,所以必须拆分为小于5的数
- 1*(n-1)<n,没必要拆分成1
- 4=2*2,只需要拆分为2或者3
- 222<3*3,所以最多有两个2,剩下的都是3
-
【470】用 Rand7() 实现 Rand10()
- 调用两次rand7生成1
49,在140范围内取最后一位数+1返回即可
- 调用两次rand7生成1