1. 程式人生 > >leetcode 刷題日誌 2018-03-26

leetcode 刷題日誌 2018-03-26

運算 dir plan push tac and 註意 搜索 數字相加

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

leetcode 刷題日誌 2018-03-26