43. 字符串相乘
题解: 模拟大数相乘, 从最后一位开始往前枚举,A[i] * B[j] 最后的结果应该位于结果数组 C[i+j+1] 位,进位结果会保存在第C[i+j]位,所以需要从后往前递推。如果当前C[i+j+1]>=10了,要对进位进行处理。
class Solution { public: string multiply(string num1, string num2) { int len1 = num1.size() , len2 = num2.size(); vector <int> ans(len1+len2); for(int i=len1-1;i>=0;i--){ for(int j=len2-1;j>=0;j--){ int now = ans[i+j+1] + (num1[i] - '0') * (num2[j] - '0'); ans[i+j+1] = now%10; ans[i+j] += now/10; } } string res; int i=0; for(i=0;i<len1+len2-1;i++){ if(ans[i]==0) continue; break; } while(i<len1+len2){ res += ans[i]+'0'; i++; } return res; } };
392. 判断子序列
直接扫描/序列自动机,这里提供序列自动机解法。
class Solution { public: int dp[500005][26]; bool isSubsequence(string s, string t) { for(int j=0;j<26;j++) dp[t.size()][j] = -1; for(int i=t.size()-1; i>=0;i--){ for(int j=0;j<26;j++) dp[i][j] = dp[i+1][j]; dp[i][t[i]-'a'] = i; } int now = 0; for(int i=0;i<s.size();i++){ if(dp[now][s[i]-'a']==-1) return false; now = dp[now][s[i]-'a'] + 1; // 不加1的话碰到aaaaa这种会原地踏步 } return true; } };
1111. 有效括号的嵌套深度
题解: 贪心,首先算出每个括号在原括号序列中的深度,计算最大深度maxd , <=maxd/2的都放A , 其余的都放B。
class Solution { public: vector<int> maxDepthAfterSplit(string seq) { vector <int> depth; stack <int> stk; int maxd = 0; for(int i=0;i<seq.size();i++){ if(seq[i]=='('){ stk.push('('); maxd = max(maxd, (int)stk.size()); depth.push_back(stk.size()); }else{ depth.push_back(stk.size()); stk.pop(); } } vector <int> ans; for(int i=0;i<depth.size();i++){ if(depth[i] <=maxd/2) ans.push_back(0); else ans.push_back(1); } return ans; } };
856. 括号的分数
题解: 使用栈进行模拟
class Solution { public: int scoreOfParentheses(string S) { stack <int> stk; for(int i=0;i<S.size();i++){ if(S[i]=='('){ // 碰到左括号直接入栈 stk.push(-1); }else{ if(stk.top()==-1){ // 如果栈顶是(,说明现在刚好配对,价值为 1 stk.pop(); stk.push(1); }else{ // 栈顶不为(, 即为(ABC)的情况,得分为(A+B+C)*2 int now = 0; while(stk.top()!=-1){ now+=stk.top(); stk.pop(); } stk.pop(); stk.push(2*now); } } } int ans = 0; while(stk.size()){ ans+=stk.top(); stk.pop(); } return ans; } };
36. 有效的数独
题解: 首先使用 row[i][num]数组对行中出现的数字进行标记, 使用col[j][num]数组对列中出现的数字进行标记,而3*3的小格子可以通过 (i/3)*3 + j/3 映射成唯一编号,使用block[(i/3)*3 + j/3][num]进行标记。
class Solution { public: bool col[9][10], row[9][10], block[9][10]; bool isValidSudoku(vector<vector<char>>& board) { for(int i=0;i<9;i++){ for(int j=0;j<9;j++){ if(board[i][j]=='.') continue; int now = board[i][j]-'0'; if(row[i][now]) return false; if(col[j][now]) return false; if(block[(i/3)*3 + j/3][now]) return false; row[i][now] = col[j][now] = block[(i/3)*3 + j/3][now] = 1; } } return true; } };