每一个数都可以分解成素数的乘积。
令 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) * …
204. Count Primes(Easy)
Count the number of prime numbers less than a non-negative number, n.
Example:
Input: 10
Output: 4
Explanation: There are 4 prime numbers less than 10, they are 2, 3, 5, 7.
问题分析:
从 2 开始,每碰见一个素数,就将该素数的所有整数倍的数排除。
class Solution {
public:
int countPrimes(int n) {
vector<bool>prime(n+1,true);
int cnt=0;
for(int i=2;i<n;i++)
{
if(prime[i])
{
cnt++;
for(int j=2;j*i<n;j++)
prime[j*i]=false;
}
}
return cnt;
}
};
504. Base 7(Easy)
Given an integer, return its base 7 string representation.
Example 1:
Input: 100
Output: “202”
Example 2:
Input: -7
Output: “-10”
Note: The input will be in range of [-1e7, 1e7].
问题分析:
将十进制的数转化为七进制的数,每次将原数取余,再除以十,这里需要考虑负数,负号单独考虑。
class Solution {
public:
string convertToBase7(int num) {
if(num==0)
return "0";
string str="";
bool isNegative=false;
while(num<0)
{
num=-num;
isNegative=true;
}
while(num>0)
{
str=to_string(num%7)+str;;
num=num/7;
}
if(isNegative)
str="-"+str;
return str;
}
};
405. Convert a Number to Hexadecimal(Easy)
Given an integer, write an algorithm to convert it to hexadecimal. For negative integer, two’s complement method is used.
Note:
Example 1:
Input:
26
Output:
“1a”
Example 2:
Input:
-1
Output:
“ffffffff”
class Solution {
public:
string toHex(int num) {
if(num==0)
return "0";
char a[]= {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
unsigned int num_uns = (num >= 0) ? num : INT_MAX*2 + 2 + num;//转为为无符号数
string result;
while(num_uns>0)
{
result=a[num_uns%16]+result;
num_uns=num_uns/16;
}
return result;
}
};
可以不创建数组,用ASCII码操作选取字符。
class Solution {
public:
string toHex(int num) {
if(num==0)
return "0";
unsigned int num_uns = (num >= 0) ? num : INT_MAX*2 + 2 + num;//转为为无符号数
string result;
while(num_uns>0)
{
int tmp=num_uns%16;
result=(tmp<=9?(char)('0'+tmp):(char)('a'+tmp-10))+result;//ASCII码操作
num_uns=num_uns/16;
}
return result;
}
};
168. Excel Sheet Column Title(Easy)
Given a positive integer, return its corresponding column title as appear in an Excel sheet.
For example:
1 -> A
2 -> B
3 -> C
…
26 -> Z
27 -> AA
28 -> AB
…
Example 1:
Input: 1
Output: “A”
Example 2:
Input: 28
Output: “AB”
Example 3:
Input: 701
Output: “ZY”
问题分析:
可以理解为将一个数转化为26进制的数,这里用递归进行操作,因为是从 1 开始计算的,而不是从 0 开始,因此需要对 n 执行 -1 操作。
class Solution {
public:
string convertToTitle(int n) {
if (n == 0)
return "";
n--;
return convertToTitle(n/26)+(char)('A' + n % 26);//注意这里的ASCII码操作
}
};
写成循环也是可以的
class Solution {
public:
string convertToTitle(int n) {
string str;
while(n>0)
{
n--;
int tmp=n%26;
str=(char)('A' + n % 26)+str;
n=n/26;
}
return str;
}
};
172. Factorial Trailing Zeroes(Easy)
Given an integer n, return the number of trailing zeroes in n!.
Example 1:
Input: 3
Output: 0
Explanation: 3! = 6, no trailing zero.
Example 2:
Input: 5
Output: 1
Explanation: 5! = 120, one trailing zero.
Note: Your solution should be in logarithmic time complexity.
问题分析:
尾部的 0 由 2 * 5 得来,2 的数量明显多于 5 的数量,因此只要统计 5 的个数。
对于 N 的阶乘,N!=1×2×3×4×5×6×……×N
所以能拿出的 5 的总数为N/5 + N/52 + N/53 + …
class Solution {
public:
int trailingZeroes(int n) {
int sum=0;
for(int i=n;i>0;i=i/5)
sum+=i/5;
return sum;
}
};
67. Add Binary(Easy)
Given two binary strings, return their sum (also a binary string).The input strings are both non-empty and contains only characters 1 or 0.
Example 1:
Input: a = “11”, b = “1”
Output: “100”
Example 2:
Input: a = “1010”, b = “1011”
Output: “10101”
给另个字符串表示两个二进制数,计算二进制加法的和。
问题分析:
从买两个二进制数的最后一位开始计算,计算每一位二者相加的值(包括进位)。
class Solution {
public:
string addBinary(string a, string b) {
string res="";
int cur=0;
int i=a.size()-1,j=b.size()-1;
while(cur>0||i>=0||j>=0)
{
if(i>=0 && a[i--]=='1')
cur++;
if(j>=0 && b[j--]=='1')
cur++;
if(cur%2)
res+='1';
else
res+='0';
cur=cur/2;
}
for(int i=0,j=res.size()-1;i<j;i++,j--)
swap(res[i],res[j]);
return res;
}
};
415. Add Strings(Easy)
Given two non-negative integers num1 and num2 represented as string, return the sum of num1 and num2.
给定两个字符串,表示两个非负的整数,求两个字符串相加的整数和。
class Solution {
public:
string addStrings(string num1, string num2) {
string res="";
int i=num1.size()-1,j=num2.size()-1;
int cur=0;
while(cur>0||i>=0||j>=0)
{
if(i>=0)
cur+=num1[i--]-'0';
if(j>=0)
cur+=num2[j--]-'0';
res+=to_string(cur%10);
cur=cur/10;
}
for(int i=0,j=res.size()-1;i<j;i++,j--)
swap(res[i],res[j]);
return res;
}
};
462. Minimum Moves to Equal Array Elements II (Medium)
Given a non-empty integer array, find the minimum number of moves required to make all array elements equal, where a move is incrementing a selected element by 1 or decrementing a selected element by 1.
You may assume the array’s length is at most 10,000.
Example:
Input:
[1,2,3]
Output:
2
Explanation:
Only two moves are needed (remember each move increments or decrements one element):
[1,2,3] => [2,2,3] => [2,2,2]
方法一:排序
将元素排序,最终肯定是要将所有的元素移动到中间的位置,首位两个数移动的距离之和为 nums[j]-nums[i]。
class Solution {
public:
int minMoves2(vector<int>& nums) {
sort(nums.begin(),nums.end());
int i=0,j=nums.size()-1;
int sum=0;
for(;i<j;i++,j--)
sum+=(nums[j]-nums[i]);
return sum;
}
};
复杂度:O(nlogn)
方法二:快速排序找中位数
class Solution {
public:
int minMoves2(vector<int>& nums) {
int sum=0;
int k=findKthSmallest(nums,nums.size()/2);
for(int num:nums)
sum+=abs(num-k);
return sum;
}
int findKthSmallest(vector<int>& nums, int k) {
int location=k;
int left=0,right=nums.size()-1;
while(left<right)
{
int privot=paititio(nums,left,right);
if(privot==location)
break;
else if(privot>location)
right=privot-1;
else
left=privot+1;
}
return nums[location];
}
int paititio(vector<int>& nums,int left,int right)
{
int i = left, j = right + 1;
while (true)
{
while (nums[++i] < nums[left] && i < right);
while (nums[--j] > nums[left] && j > left);
if (i >= j)
break;
swap(nums[i], nums[j]);
}
swap(nums[left], nums[j]);
return j;
}
};
复杂度:O(n)
169. Majority Element(Easy)
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.You may assume that the array is non-empty and the majority element always exist in the array.
Example 1:
Input: [3,2,3]
Output: 3
Example 2:
Input: [2,2,1,1,1,2,2]
Output: 2
方法一:排序,取中间的元素
class Solution {
public:
int majorityElement(vector<int>& nums) {
sort(nums.begin(),nums.end());
return nums[nums.size()/2];
}
};
复杂度:O(nlogn)
方法二:抵消不相等的两个数
把不相等的数抵消,剩下的一定是出现次数大于 n/2 的数。
例子:[7, 7, 5, 7, 5, 1 | 5, 7 | 5, 5, 7, 7 | 7, 7, 7, 7]
假设第一个数为出现次数大于 n/2 的数,计算该数出现的次数比其他数出现的次数多多少,每当全部抵消时,重新假设出现次数大于 n/2 的数。
初始化:major=7,cnt=0
在下标为 5 的时候抵消,重新赋值major=5,cnt=0
在下标为 7 的时候抵消,重新赋值major=5,cnt=0
在下标为 11 的时候抵消,重新赋值major=7,cnt=0
最终major=7,cnt=4
class Solution {
public:
int majorityElement(vector<int>& nums) {
int cnt=0,major=nums[0];
for(int n:nums)
{
major=(cnt==0?n:major);
cnt=(n==major?cnt+1:cnt-1);
}
return major;
}
};
复杂度:O(n)
367. Valid Perfect Square(Easy)
Given a positive integer num, write a function which returns True if num is a perfect square else False.
Note: Do not use any built-in library function such as sqrt.
Example 1:
Input: 16
Output: true
Example 2:
Input: 14
Output: false
方法一:二分
class Solution {
public:
bool isPerfectSquare(int num) {
int left=1,right=num;
double mid;
while(left<=right)
{
mid=left+(right-left)/2;
double tmp=num/mid;
if(tmp==mid)
return true;
else if(mid>tmp)
right=mid-1;
else
left=mid+1;
}
return false;
}
};
方法一:
平方数序列为:1,4,9,16,25……
两数间隔为:3,5,7,9……
两个平方数之间的间隔为等差数列
对目标数依次减 1,3,5,7,9……,如果可以减到 0,说明是平方数。
class Solution {
public:
bool isPerfectSquare(int num) {
int cnt=1;
while(num>0)
{
num-=cnt;
cnt+=2;
}
return num==0?true:false;
}
};
326. Power of Three(Easy)
class Solution {
public:
bool isPowerOfThree(int n) {
if(n<1)return false;
while(n>1)
{
if(n%3)return false;
n=n/3;
}
return true;
}
};
238. Product of Array Except Self(Medium)
给一个 n 个整数的数组,返回一个数组,使得 output [i] 等于除 nums [i] 之外的所有 nums 元素的乘积。
要求时间复杂度为 O(n),不能使用除法,空间复杂度为 O(1),不包括返回的而数组。
Example:
Input: [1,2,3,4]
Output: [24,12,8,6]
方法一:分别构造左右乘积数组
先介绍一种空间复杂度为 O(n) 的方法,定义两个数组 left[] 和 right[],left[i] 表示 i 元素之前的所有元素的乘积,right[i] 表示 i 元素之后的所有的元素乘积。则 left[] * right[] 就是除 i 元素外所有元素的乘积。
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int n = nums.size();
vector<int>left(n, 1);
vector<int>right(n, 1);
vector<int>res(n, 1);
for(int i = 1; i < n; i++)
left[i] = left[i-1] * nums[i-1];
for(int i = n-2; i >= 0; i--)
right[i] = right[i+1] * nums[i+1];
for(int i = 0; i < n; i++)
res[i] = left[i] * right[i];
return res;
}
};
方法二:空间优化
将返回数组计算为左乘积数组,left[i] 就表示 i 元素之前的所有元素的乘积,从右向左遍历数组,每到一个位置,令整数right = right * nums[i+1],保证 right 等于该位置之后所有元素乘积。
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums) {
int n = nums.size();
vector<int>res(n, 1);
for(int i = 1; i < n; i++)
res[i] = res[i-1] * nums[i-1];
int right = 1;
for(int i = n-2; i >= 0; i--){
right *= nums[i+1];
res[i] = res[i] * right;
}
return res;
}
};
628. Maximum Product of Three Numbers(Easy)
Example 1:
Input: [1,2,3]
Output: 6
Example 2:
Input: [1,2,3,4]
Output: 24
解题思路:数组中可能会出现负数,找出数组中最大的三个数 a1,a2,a3 和最小的两个数 b1,b2,结果为 max(a1a2a3, a1b1b2)
class Solution {
public:
int maximumProduct(vector<int>& nums) {
int n = nums.size();
int res = 1;
vector<int>big(3,INT_MIN);
vector<int>small(2,INT_MAX);
for(int i = 0; i <n; i++){
if(nums[i] > big[2]){
if(nums[i] > big[0]){
big[2] = big[1];
big[1] = big[0];
big[0] = nums[i];
}
else if(nums[i] > big[1]){
big[2] = big[1];
big[1] = nums[i];
}
else if(nums[i] > big[2])
big[2] = nums[i];
}
if (nums[i] < small[1]){
if(nums[i] < small[0]){
small[1] = small[0];
small[0] = nums[i];
}
else if(nums[i] < small[1])
small[1] = nums[i];
}
}
return max(big[0]*big[1]*big[2], big[0]*small[0]*small[1]);
}
};