leetcode高效制胜 6 数字
119. 杨辉三角 II
给定一个非负索引 rowIndex,返回「杨辉三角」的第 rowIndex 行。
在「杨辉三角」中,每个数是它左上方和右上方的数的和。
示例 1:
输入: rowIndex = 3
输出: [1,3,3,1]
示例 2:
输入: rowIndex = 0
输出: [1]
示例 3:
输入: rowIndex = 1
输出: [1,1]
提示:
0 <= rowIndex <= 33
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int>dp(rowIndex+1,0);
dp[0]=1;
for(int i=1;i<=rowIndex;i++){
for(int j=i;j>0;j--){
dp[j]=dp[j]+dp[j-1];
}
}
return dp;
}
};
- 将第二层循环倒过来,就可以实现O(rowIndex)的空间复杂度
线性递推:
class Solution {
public:
vector<int> getRow(int rowIndex) {
vector<int> row(rowIndex + 1);
row[0] = 1;
for (int i = 1; i <= rowIndex; ++i) {
row[i] = 1LL * row[i - 1] * (rowIndex - i + 1) / i;
}
return row;
}
};
作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/pascals-triangle-ii/solution/yang-hui-san-jiao-ii-by-leetcode-solutio-shuk/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
279. 完全平方数(!!!)
给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, …)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。
给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。
完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,1、4、9 和 16 都是完全平方数,而 3 和 11 不是。
示例 1:
输入:n = 12
输出:3
解释:12 = 4 + 4 + 4
示例 2:
输入:n = 13
输出:2
解释:13 = 4 + 9
提示:
1 <= n <= 104
数学:
class Solution {
public:
bool isSquare(int n){
int i=sqrt(n);
if(i*i==n)return 1;
return 0;
}
bool isAnswer4(int n){
while(n%4==0){
n=n/4;
}
return n%8==7;
}
int numSquares(int n) {
if(isSquare(n))return 1;
if(isAnswer4(n))return 4;
for(int i=1;i*i<=n;i++){
int k=n-i*i;
if(isSquare(k))return 2;
}
return 3;
}
};
动态规划:
class Solution {
public:
int numSquares(int n) {
vector<int> dp(n+1,10000);
dp[0]=0;
for(int i=1;i<=n;i++){
for(int j=1;j*j<=i;j++){
dp[i]=min(dp[i],dp[i-j*j]+1);
}
}
return dp[n];
}
};
- 数学时间复杂度为O(n1/2)
- 动态规划时间复杂度为O(n*n1/2)
- 有个数学定理,叫四平方和定理:一个数最多是4个数的平方之和,当n!=4k(8m+7)时,可能是1、2、3
- 动态规划:一看到题目就想到了昨天写的动态规划,硬币之和最少
483. 最小好进制(!!!)
对于给定的整数 n, 如果n的k(k>=2)进制数的所有数位全为1,则称 k(k>=2)是 n 的一个好进制。
以字符串的形式给出 n, 以字符串的形式返回 n 的最小好进制。
示例 1:
输入:“13”
输出:“3”
解释:13 的 3 进制是 111。
示例 2:
输入:“4681”
输出:“8”
解释:4681 的 8 进制是 11111。
示例 3:
输入:“1000000000000000000”
输出:“999999999999999999”
解释:1000000000000000000 的 999999999999999999 进制是 11。
提示:
n的取值范围是 [3, 10^18]。
输入总是有效且没有前导 0。
class Solution {
public:
string smallestGoodBase(string n) {
long num=stol(n);
int bitLength = (int)(log(num*1.0)/log(2));
for(int s=bitLength;s>=2;s--){
long k=powl(num,1.0/s);
//cout<<s<<' '<<k<<endl;
long sum=1;
long res=1;
for(int i=1;i<=s;i++){
res*=k;
sum+=res;
}
if(sum==num)return to_string(k);
}
return to_string(num-1);
}
};
题解:https://leetcode-cn.com/problems/smallest-good-base/solution/zui-xiao-hao-jin-zhi-er-fen-shu-xue-fang-frrv/
- 很多数学思想,等比数列、二项式定理等,但是想不到啊
- 注意溢出:
res*=k; sum+=res;
这两句可不能倒过来写!!! - stringstream真的好用,to_string,stoi,stol等
二分求k:
class Solution {
public:
string smallestGoodBase(string n) {
long num=stol(n);
int bitLength = (int)(log(num*1.0)/log(2));
for(int s=bitLength;s>=2;s--){
long l=2,r=num-1;
while(l<=r){
long mid=(r-l)/2+l;
long k=mid;
long maxVal=num/mid+1;
long sum=1;
for(int i=1;i<=s;i++){
if(sum<maxVal){
sum=sum*k+1;
}else {
sum=num+1;
break;
}
}
if(sum==num)return to_string(k);
else if(sum<num) l=mid+1; //k偏小
else r=mid-1;
//cout<<s<<' '<<k<<endl;
}
}
return to_string(num-1);
}
};
- 学到了反向防止溢出
- 二分法得到了巩固
数学题真的不简单不简单