LeetCode [ Day1 ]
整数反转
【收获】
1、拆解整数的两种方式
(1)从后往前,ans + = 此位数不断乘10;
(2)从后往前,ans = ans * 10 + 此位数。
2、C++中整型上下限表示:
上限 - INT_MAX
下限 - INT_MIN
3、数是否溢出整型的判断
【注意】
(1)先判断,后加数;
(2)利用位数和个数。
【AC代码】
typedef long long ll;
int reverse(int x) {
int ans=0;
while(x){
int num=x%10;
x/=10;
if(ans>INT_MAX/10 || (ans==INT_MAX/10 && num>INT_MAX%10))
return 0;
if(ans<INT_MIN/10 || (ans==INT_MIN/10 && num<INT_MIN%10))
return 0;
ans=ans*10+num;
}
return ans;
}
整数转罗马数字
【做题】
之前遇到的整数提取,都是从后往前;这次要求从前往后,给我整不会了。
也没有想到可以用数组去存,或者是不断地减大数。
用“AC代码2”解决方案最好。
【收获】
1、数位的提取;
2、pair<>用法巩固 + for迭代器 + for对pair的迭代;
3、调用函数耗时蛮多的。
【AC代码1】强破解
const string thousands[]={"","M","MM","MMM"};
const string hundreds[] ={"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
const string tens[] ={"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
const string ones[] ={"","I","II","III","IV","V","VI","VII","VIII","IX"};
class Solution {
public:
string intToRoman(int num) {
return thousands[num/1000]+hundreds[num%1000/100]+tens[num%100/10]+ones[num%10];
}
};
【AC代码2】模拟
const pair<int,string> valueSymbols[]={
{1000,"M"},
{900,"CM"},
{500,"D"},
{400,"CD"},
{100,"C"},
{90,"XC"},
{50,"L"},
{40,"XL"},
{10,"X"},
{9,"IX"},
{5,"V"},
{4,"IV"},
{1,"I"},
};
class Solution {
public:
string intToRoman(int num) {
string ans="";
for(const auto&[value,symbols]:valueSymbols){
while(num>=value){
num-=value;
ans+=symbols;
}
if(num==0) break;
}
return ans;
}
};
【AC代码3】枚举
class Solution {
public:
string intToRoman(int num) {
string ans="",temp;
int cnt=0,bit;
while(num){
cnt++;
bit=num%10;
if(cnt==1){
if(bit==0) temp="";
else if(bit==1) temp="I";
else if(bit==2) temp="II";
else if(bit==3) temp="III";
else if(bit==4) temp="IV";
else if(bit==5) temp="V";
else if(bit==6) temp="VI";
else if(bit==7) temp="VII";
else if(bit==8) temp="VIII";
else if(bit==9) temp="IX";
}
else if(cnt==2){
if(bit==0) temp="";
else if(bit==1) temp="X";
else if(bit==2) temp="XX";
else if(bit==3) temp="XXX";
else if(bit==4) temp="XL";
else if(bit==5) temp="L";
else if(bit==6) temp="LX";
else if(bit==7) temp="LXX";
else if(bit==8) temp="LXXX";
else if(bit==9) temp="XC";
}else if(cnt==3){
if(bit==0) temp="";
else if(bit==1) temp="C";
else if(bit==2) temp="CC";
else if(bit==3) temp="CCC";
else if(bit==4) temp="CD";
else if(bit==5) temp="D";
else if(bit==6) temp="DC";
else if(bit==7) temp="DCC";
else if(bit==8) temp="DCCC";
else if(bit==9) temp="CM";
}else if(cnt==4){
if(bit==0) temp="";
else if(bit==1) temp="M";
else if(bit==2) temp="MM";
else if(bit==3) temp="MMM";
}
ans.insert(0,temp);
num/=10;
}
return ans;
}
};
两数相除
【做题】
一看到不能用 * 、/ 和 mod,一下子就惊了一下;然后又想到了除法的原理,暴力求解,然后超时……
指数求解,刚开始也没用temp,忽略了dividend_long可以反复减去“小的数”。
【收获】
异号判断(不能有==1 !!!);
【AC代码】
typedef long long ll;
class Solution {
public:
int divide(int dividend, int divisor) {
int sign=((dividend^divisor)>>31) ? -1:1;
long result=0;
long dividend_long=abs((long)dividend);
long divisor_long=abs((long)divisor);
while(dividend_long >= divisor_long){
long i=1;
long temp=divisor_long;
while(dividend_long >= temp){ //不能缺少temp!有可能出现被除数仍比除数小的情况
dividend_long -= temp;
result+=i;
i<<=1;
temp<<=1;
}
}
result*=sign;
if(result<INT_MIN || result>INT_MAX)
return INT_MAX;
return (int)result;
}
};
黑白方格
【做题】
一直想着怎么利用组合数去选择,没有想到选择的 row 和 col 之间与 k 的关系。数量规模小,暴力求解确实不错……
【收获】
1、逆向判断。
【AC代码】
int C[10][10];
class Solution {
public:
int paintingPlan(int n, int k) {
if(k==n*n || k==0) return 1;
if(k<n) return 0;
for(int i=0;i<10;i++)
for(int j=0;j<10;j++)
if(!j) C[i][j]=1;
else if(i!=0) C[i][j]=C[i-1][j]+C[i-1][j-1];
int ans=0;
for(int i=0;i<=n;i++)
for(int j=0;j<=n;j++)
if(i*n+j*n-i*j==k) //!!!
ans+=C[n][i]*C[n][j];
return ans;
}
};
好菜啊我……