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
intreverse(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