leetcode 刷题日志 2018-03-26

 

 

 

58. 最后一个单词的长度

分析:找最后一个非空格,向前找

int lengthOfLastWord(string s) {
        int i = s.find_last_not_of(' ');
        int j = i;
        for(;j >= 0; j--){
            if(s[j] == ' ')
                break;
        }
        return i - j;
    }

 

7. 颠倒整数

分析:注意题意,超范围 LL ,结尾去0

int reverse(int x) {
        long long res = 0;
        if(x!=0){
            while(!x%10){
                x /= 10;
            }
        }
        while(x){
            res *= 10;
            res += x % 10;
            x /= 10;
        }
        if(res> INT_MAX || res < -INT_MAX){
            res = 0;
        }
        return res;
    }

 13. 罗马数字转整数

分析:罗马数字共有7个,即Ⅰ(1)、Ⅴ(5)、Ⅹ(10)、Ⅼ(50)、Ⅽ(100)、Ⅾ(500)和Ⅿ(1000)。按照下述的规则可以表示任意正整数。需要注意的是罗马数字中没有“0”,与进位制无关。一般认为罗马数字只用来记数,而不作演算。

字母对应数字相加,后面字母比前面字母大代表前面字母需要减去

被减的字母最多一个!

int singleCharToInt(char x){
        int num = -1;
        if(x == 'i')
            num = 1;
        else if(x == 'v')
            num = 5;
        else if(x == 'x')
            num = 10;
        else if(x == 'l')
            num = 50;
        else if(x == 'c')
            num = 100;
        else if(x == 'd')
            num = 500;
        else if(x == 'm')
            num = 1000;
        return num;
    }
    int romanToInt(string s) {
        int len = s.size();
        transform(s.begin(), s.end(), s.begin(), ::tolower);
        int res = 0;
        for(int i=0;i<len;i++){
            int num=singleCharToInt(s[i]);
            if(singleCharToInt(s[i+1]) > num){
                num=(-1)*num;
            }
            res += num;
        }
        return res;
    }

 38. 数数并说

分析:步步迭代

整数字符串转换

string fun(string s){
    string tmp = "";
    int len = s.size();
    int con =0;
    char t ;
    for(int i=0;i<len;){
        t=s[i++];con = 1;
        while(s[i] == t){
            con++; i++;
        }
        ostringstream stream;
        stream<<con;  //n为int类型
        tmp =tmp + stream.str();
        tmp+=t;
    }
    return tmp;
}
string countAndSay(int n) {
    string s="1";
    int en = s.size();
    int con =0;
    while(--n){
        s=fun(s);
        //cout<<s<<endl;
    }
    return s;
}

 

67. 二进制求和

分析:对齐,相加,首位进位处理

string addBinary(string a, string b) {
        //对齐
        int lena = a.size(), lenb = b.size();
        int n = abs(lena - lenb);
        string tmp(n,'0');
        if(lena < lenb) { a = tmp + a; }
        if(lena > lenb) { b = tmp + b; }
        //加法
        int len = a.size();
        int x = 0, c = 0; // 计算结果,进位标记
        for(int i = len - 1; i >= 0; --i){
            x = a[i] - '0' + b[i] -'0' + c;
            if( x > 1){
                c = 1;
                x -= 2;
            }
            else{
                c = 0;
            }
            a[i] = (char)('0' + x );
        }
        if(c) //首部进位
            a = "1" + a;
        return a;
    }

 

14. 最长公共前缀

分析:拿第一个字符串作为标准,遍历所有字符串,期间不断缩小条件

string longestCommonPrefix(vector<string>& strs) {
        int len = strs.size(),lenS = 0;
        if(0 == len)
            return "";
        string s = strs[0];
        for(int i=0; i<len; ++i){
            lenS = s.length();
            for(int j=0; j<lenS; ++j){
                if(s[j] != strs[i][j]){
                    s = s.substr(0 , j); //对比所有字符串,不断缩减条件
                    break;
                }
            }
        }
        return s;
    }

 20. 有效的括号

给定一个只包括 '('')''{''}''['']' 的字符串,判断字符串是否有效。

括号必须以正确的顺序关闭,"()" 和 "()[]{}" 是有效的但是 "(]" 和 "([)]" 不是。

分析:栈的应用

我用的比较别扭

每次压入一个字符,深入栈内看是否还有配对成功的括号可以弹出

最终所有配对成功的话,栈为空

 

bool isValid(string s) {
    stack<char> stack_tmp;
    int len = s.length();
    char x,y;
stack_tmp.push(s[
0]); for(int i=1; i<len; i++){ stack_tmp.push(s[i]); while(stack_tmp.size()>=2){ //要想配对成功,至少有两个 y = stack_tmp.top(); stack_tmp.pop(); x = stack_tmp.top(); //取两数 if(')' == y && x == '('){ stack_tmp.pop(); } else if('}' == y && x == '{'){ stack_tmp.pop(); } else if(']' == y && x == '['){ stack_tmp.pop(); } else{ stack_tmp.push(y); //不行,再压回去 break; } } } return stack_tmp.empty(); }

 29. 两数相除

不使用乘号,除号和取模符号将两数相除。如果溢出返回 MAX_INT。

感谢:https://www.liuchuo.net/archives/3140

//1. 利用 a/b = exp(log(a)-log(b))  //注意定义域>0 需取绝对值,并抽取符号位(抑或运算用的巧妙)
//2. 注意越界情况,可能分母==0 可能负数反号
int
divide(int dividend, int divisor) { if(divisor == 0 || dividend == INT_MIN && divisor == -1) return INT_MAX; //溢出两种情况 int sign = ((dividend >> 31) ^ (divisor >> 31)) == 0 ? 1 : -1; //符号位 判断 long a = abs((long)dividend); long b = abs((long)divisor); double c = exp(log(a) - log(b)) + 0.0000000001; return (int)(sign * c); }

 

125. 验证回文字符串

给定一个字符串,确定它是否是回文,只考虑字母数字字符和忽略大小写。

例如:
"A man, a plan, a canal: Panama" 是回文字符串。
"race a car" 不是回文字符串。

注意:
你有考虑过这个字符串可能是空的吗? 在面试中这是一个很好的问题。

针对此题目,我们将空字符串定义为有效的回文字符串。

分析:空串处理、提取主要字符串、双向搜索判断

bool isPalindrome(string s) {
    if (""== s) return true; //1. deal with empty string
    int len = s.length();
    string tmp="";
    for(int i=0; i <len; i++){  //2. filter string
        if(s[i]>='A' &&s[i]<='Z'){
            tmp +=s[i] +32;
        }
        if((s[i]>='a'&& s[i]<='z') ||(s[i] >='0' &&s[i] <='9')){
            tmp +=s[i];
        }
    }
    len = tmp.length();
    int m = (len +1)/2;
    for (int i=0; i <= m; i++) { //3. Bidirectional search
        if(tmp[i] != tmp[len -i -1])
            return false;
    }
    return true;
}

 

posted @ 2018-03-30 10:56  kimsimple  阅读(272)  评论(0编辑  收藏  举报