LeetCode

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;
    }
};

好菜啊我……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值