素数分解 | ||
整除 | ||
最大公约数最小公倍数 | ||
1. 生成素数序列 | 思考后可做出Ok |
|
2. 最大公约数 |
|
|
3. 使用位操作和减法求解最大公约数 |
|
|
进制转换 | ||
1. 7 进制 | 思考后可做出Ok |
|
2. 16 进制 | 一开始未做出 | ※ |
3. 26 进制 | 解法可优化 | ※ |
阶乘 | ||
1. 统计阶乘尾部有多少个 0 | 解法可优化 | ※ |
字符串加法减法(2.21) | ||
1. 二进制加法 | 一开始可做出Ok |
|
2. 字符串加法 | 一开始可做出Ok |
|
相遇问题 | ||
1. 改变数组元素使所有的数组元素都相等 | 一开始未做出 | ※ |
多数投票问题 | ||
1. 数组中出现次数多于 n / 2 的元素 | 解法可优化 | ※ |
其它 | ||
1. 平方数 | 一开始可做出, 有其他方法可参考 | ※ |
2. 3 的 n 次方 | 一开始可做出Ok |
|
3. 乘积数组 | 思考后可做出Ok |
|
4. 找出数组中的乘积最大的三个数 | 一开始未做出 | ※ |
素数分解
每一个数都可以分解成素数的乘积,例如 84 = 22 * 31 * 50 * 71 * 110 * 130 * 170 * …
整除
令 x = 2m0 * 3m1 * 5m2 * 7m3 * 11m4 * …
令 y = 2n0 * 3n1 * 5n2 * 7n3 * 11n4 * …
如果 x 整除 y(y mod x == 0),则对于所有 i,mi <= ni。
最大公约数最小公倍数
x 和 y 的最大公约数为:gcd(x,y) = 2min(m0,n0) * 3min(m1,n1) * 5min(m2,n2) * ...
x 和 y 的最小公倍数为:lcm(x,y) = 2max(m0,n0) * 3max(m1,n1) * 5max(m2,n2) * ...
1. 生成素数序列
204. Count Primes (Easy)
https://leetcode-cn.com/problems/count-primes/
2. 最大公约数
int gcd(int a, int b) {
return b == 0 ? a : gcd(b, a % b);
}
最小公倍数为两数的乘积除以最大公约数。
int lcm(int a, int b) {
return a * b / gcd(a, b);
}
3. 使用位操作和减法求解最大公约数
对于 a 和 b 的最大公约数 f(a, b),有:
- 如果 a 和 b 均为偶数,f(a, b) = 2*f(a/2, b/2);
- 如果 a 是偶数 b 是奇数,f(a, b) = f(a/2, b);
- 如果 b 是偶数 a 是奇数,f(a, b) = f(a, b/2);
- 如果 a 和 b 均为奇数,f(a, b) = f(b, a-b);
乘 2 和除 2 都可以转换为移位操作。
public int gcd(int a, int b) {
if (a < b) {
return gcd(b, a);
}
if (b == 0) {
return a;
}
boolean isAEven = isEven(a), isBEven = isEven(b);
if (isAEven && isBEven) {
return 2 * gcd(a >> 1, b >> 1);
} else if (isAEven && !isBEven) {
return gcd(a >> 1, b);
} else if (!isAEven && isBEven) {
return gcd(a, b >> 1);
} else {
return gcd(b, a - b);
}
}
进制转换
1. 7 进制
504. Base 7 (Easy)
https://leetcode-cn.com/problems/base-7/
2. 16 进制
405. Convert a Number to Hexadecimal (Easy)
https://leetcode-cn.com/problems/convert-a-number-to-hexadecimal/
可使用位运算加快速度!
class Solution {
public:
string s[16]={"0","1","2","3","4","5","6","7","8","9","a","b","c","d","e","f"};
string toHex(int num) {
if(num==0) return "0";
string res;
while(num&&res.size()<8){ //注意限制长度:针对负数
res=s[num&0xf]+res;
num>>=4;
}
return res;
}
};
3. 26 进制
168. Excel Sheet Column Title (Easy)
https://leetcode-cn.com/problems/excel-sheet-column-title/
class Solution {
public:
string convertToTitle(int n) {
string res;
while(n--){
res=(char)('A'+n%26)+res;
n/=26;
}
return res;
}
};
阶乘
1. 统计阶乘尾部有多少个 0
172. Factorial Trailing Zeroes (Easy)
https://leetcode-cn.com/problems/factorial-trailing-zeroes/
尾部的 0 由 2 * 5 得来,2 的数量明显多于 5 的数量,因此只要统计有多少个 5 即可。
对于一个数 N,它所包含 5 的个数为:N/5 + N/52 + N/53 + ...,其中 N/5 表示不大于 N 的数中 5 的倍数贡献一个 5,N/52 表示不大于 N 的数中 52 的倍数再贡献一个 5 ...。
class Solution {
public:
int trailingZeroes(int n) {
int five=0;
while(n/=5)
five+=n;
return five;
}
};
字符串加法减法
1. 二进制加法
67. Add Binary (Easy)
https://leetcode-cn.com/problems/add-binary/
2. 字符串加法
415. Add Strings (Easy)
https://leetcode-cn.com/problems/add-strings/
相遇问题
1. 改变数组元素使所有的数组元素都相等
462. Minimum Moves to Equal Array Elements II (Medium)
https://leetcode-cn.com/problems/minimum-moves-to-equal-array-elements-ii
移动距离最小的方式是所有元素都移动到中位数。
设 m 为中位数。a 和 b 是 m 两边的两个元素,且 b > a。要使 a 和 b 相等,它们总共移动的次数为 b - a,这个值等于 (b - m) + (m - a),也就是把这两个数移动到中位数的移动次数。
设数组长度为 N,则可以找到 N/2 对 a 和 b 的组合,使它们都移动到 m 的位置。
1. 先排序
class Solution {
public:
int minMoves2(vector<int>& nums) {
sort(nums.begin(),nums.end());
int sum=0;
for(int l=0,h=nums.size()-1;l<h;l++,h--)
sum+=nums[h]-nums[l];
return sum;
}
};
2. 快排
class Solution {
public:
void swap(int &a,int &b){
int t=a;
a=b;
b=t;
}
int partition(vector<int>& nums,int left,int right){
int privot=nums[right];
int i=left,j=right-1;
while(true){
while(i<right&&nums[i]<privot) i++; //重要
while(j>=left&&nums[j]>=privot) j--;
if(i>=j) break;
swap(nums[i],nums[j]);
}
swap(nums[i],nums[right]);
return i;
}
int select(vector<int>& nums,int k){
int l=0,r=nums.size()-1;
while(l<r){
int index=partition(nums,l,r);
if(index==k) break;
else if(index<k) l=index+1;
else r=index-1;
}
return nums[k];
}
int minMoves2(vector<int>& nums) {
int mid=select(nums,nums.size()>>1),sum=0;
for(int num:nums)
sum+=abs(num-mid);
return sum;
}
};
多数投票问题
1. 数组中出现次数多于 n / 2 的元素
169. Majority Element (Easy)
https://leetcode-cn.com/problems/majority-element/
- 先排序,取中位数
用库函数/快排,同上一题。
- 剔除元素法
在原序列中去除两个不同的元素后,原序列中的多数元素在新序列中还是多数元素。
1)将数组的第一个元素设置为多数元素P,并记录count = 1
2)将数组后面的数与P比较,若相等count+1,不相等count-1,
3)若count减到0,便表示该元素出现次数太少,将其和后面一个不相等的元素剔除,再次重置c和count
4)继续此操作,直到比较到最后count都不为0,则c就为多数元素。
class Solution {
public:
int majorityElement(vector<int>& nums) {
int major=nums[0],cnt=0;
for(int num:nums){
if(cnt==0) major=num;
if(major==num) cnt++;
else cnt--;
}
return major;
}
};
其它
1. 平方数
367. Valid Perfect Square (Easy)
https://leetcode-cn.com/problems/valid-perfect-square/
1. 直接计算:时间复杂度为O(logN)
class Solution {
public:
bool isPerfectSquare(int num) {
for(int i=1;i<=num/i;i++)
if(i*i==num) return true;
return false;
}
};
2. 减法:时间复杂度为O(logN)
平方序列:1,4,9,16,..
间隔:3,5,7,...
间隔为等差数列,使用这个特性可以得到从 1 开始的平方序列。
class Solution {
public:
bool isPerfectSquare(int num) {
for(int i=1;num>0;i+=2)
num-=i;
return num==0;
}
};
2. 3 的 n 次方
326. Power of Three (Easy)
https://leetcode-cn.com/problems/power-of-three/
3. 乘积数组
238. Product of Array Except Self (Medium)
https://leetcode-cn.com/problems/product-of-array-except-self/
4. 找出数组中的乘积最大的三个数
628. Maximum Product of Three Numbers (Easy)
https://leetcode-cn.com/problems/maximum-product-of-three-numbers/
1. 先排序
我们将数组进行升序排序,
如果数组中所有的元素都是非负数,那么答案即为最后三个元素的乘积。
如果数组中出现了负数,那么我们还需要考虑乘积中包含负数的情况,显然选择最小的两个负数和最大的一个正数是最优的,即为前两个元素与最后一个元素的乘积。
class Solution {
public:
int maximumProduct(vector<int>& nums) {
sort(nums.begin(),nums.end());
return max(nums[0]*nums[1]*nums[nums.size()-1],nums[nums.size()-3]*nums[nums.size()-2]*nums[nums.size()-1]);
}
};
2. 线性扫描
在方法一中,我们实际上只要求出数组中最大的三个数以及最小的两个数,因此我们可以不用排序,用线性扫描直接得出这五个数。
class Solution {
public:
int maximumProduct(vector<int>& nums) {
int min1=INT_MAX,min2=INT_MAX,max1=INT_MIN,max2=INT_MIN,max3=INT_MIN;
for(int num:nums){
if(num<min1){
min2=min1;
min1=num;
}else if(num<min2)
min2=num;
if(num>max1){
max3=max2;
max2=max1;
max1=num;
}else if(num>max2){
max3=max2;
max2=num;
}else if(num>max3)
max3=num;
}
return max(min1*min2*max1,max3*max2*max1);
}
};