1. 程式人生 > >一些leetcode算法題

一些leetcode算法題

遇到 記錄 一般來說 兩種 aaa 葉子 sub count led

DFS算法
思想:一直往深處走,直到找到解或者走不下去為止
DFS(dep,...) // dep代表目前DFS的深度
{
    if (找到解或者走不下去了){
       return;
    }
    枚舉下種情況,DFS(dep + 1, ...)
}

DFS: 使用棧保存未被檢測的節點,結點按照深度優先的次序被訪問並依次壓入棧中,並以相反的次序出棧進行新的檢測
     類似於樹的先根遍歷,深搜的例子:走迷宮,沒有辦法用分身術來站在每一個走過的位置。
例子:
leetcode 394  

class Solution {
public:
     string DFS(string
s, int &k){ // 在所有的層中是維護一個共同的索引值k string ans; int cnt = 0; while(k < s.size()) { if(isdigit(s[k])){ // 判斷是否是數字 cnt = cnt * 10 + s[k++]-0; // 如果是遇到100這樣的數字,那麽則需要這樣處理 } else if(s[k]==[){ // 如果是左括號,則要進入下層遞歸
string tem = DFS(s, ++k); // 遞歸調用 for(int i = 0; i < cnt; i++){ ans += tem; } cnt = 0; // } else if(s[k]==]){ k++; return ans; }
else ans += s[k++]; // 若是普通數字就直接加上 } return ans; } string decodeString(string s){ string res; int k = 0; return DFS(s, k); } }; leetcode 467 Unique Substring in Wraparounding string 思路:這道題說有一個無限長的封裝字符串,然後又給了我們另一 個字符串p,問我們p有多少非空子字符串在封裝字符串中。我們通過 觀察題目中的例子可以發現,由於封裝字符串是26個字符按順序無限 循環組成的,那麽滿足題意的p的子字符串要麽是單一的字符,要麽是 按字母順序的子字符串。這道題遍歷p的所有子字符串會TLE,因為如 果p很大的話,子字符串很多,會有大量的滿足題意的重復子字符串, 必須要用到trick,而所謂技巧就是一般來說你想不到的方法。我們看 abcd這個字符串,以d結尾的子字符串有abcd, bcd, cd, d,那麽我們 可以發現bcd或者cd這些以d結尾的字符串的子字符串都包含在abcd中, 那麽我們知道以某個字符結束的最大字符串包含其他以該字符結束的字符 串的所有子字符串,說起來很拗口,但是理解了我上面舉的例子就行。 那麽題目就可以轉換為分別求出以每個字符(a-z)為結束字符的最長連續 字符串就行了,我們用一個數組cnt記錄下來,最後再求出數組cnt的所有 數字之和就是我們要的結果啦 class Solution { public: int findSubstringInWraproundString(string p) { // 很有技巧的一個題 vector<int> cnt(26, 0); // 對應26個字母,註意vector的初始化 int len = 0; for (int i = 0; i < p.size(); ++i) { if (i > 0 && (p[i] == p[i - 1] + 1 || p[i - 1] - p[i] == 25)) { ++len; } else { len = 1; // 若是不再連續就將len置1重新開始 } cnt[p[i] - a] = max(cnt[p[i] - a], len); // 用len的值更新cnt的值 } return accumulate(cnt.begin(), cnt.end(), 0); // 將cnt的所有的值累加起來 } }; leetcode 647. Palindromic Substrings 回文字串 題目: Given a string, your task is to count how many palindromic substrings in this string. The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters. Example 1: Input: "abc" Output: 3 Explanation: Three palindromic strings: "a", "b", "c". Example 2: Input: "aaa" Output: 6 Explanation: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa". 思路一:dp思想 參考鏈接:http://blog.csdn.net/lishichengyan/article/details/77103324 定義d[i][j]:若從i到j的字符串為回文,則為真(1),否則為假(0),那麽d[i][j]為真的前提是:頭尾兩個字符串相同並且去掉頭尾以後的字串也是 回文(即d[i+1][j-1]為真),這裏面要註意特殊情況,即:去掉頭尾以後為空串,所以如果j-i<3,並且頭尾相等,也是回文的。 class Solution { public: int countSubstrings(string s) { int n = s.size(), count = 0; vector<vector<int>> dp(n, vector<int> (n)); //二維vector初始化,打表 for ( int end = 0; end < n; ++end ) { dp[end][end] = 1; // 每一個字符都是一個回文 ++count; for ( int start = 0; start < end; ++start ) { if ( s[start] == s[end] && (start+1 >= end-1 || dp[start+1][end-1])) { dp[start][end] = 1; ++count; // 有一個為真那麽結果值就加一 } } } return count; } }; 題意是給你一個字符串,求它有多少個回文子串。註意回文子字符串有奇數和偶數兩種形式,1,奇數 以字符串每一個字符為回文中心,然後向兩邊擴散,求以每個中心獲得的回文子串個數,然後加起來。 2. 偶數。把每個i位置作為最中間兩個字符的左邊那個,即i,i+1兩個數是回文中心。把奇數和偶數的情況加起來就是 結果 思路二: 使用從 中心向外擴展的方法,註意回文的字符串個數為奇數或者偶數的時候 class Solution { public: int helper(string s, int start, int end){ int res = 0; int len = s.size(); while (start >= 0 && end <= len && s[start] == s[end]){ res++; start--; end++; } return res; } int countSubstrings(string s) { int len = s.size(), cnt = 0; for (int i = 0; i < len; i++){ cnt += helper(s, i, i); // 回文為奇數的時候 cnt += helper(s, i, i + 1); // 回文為偶數的時候 } return cnt; } }; Leetcode 682. Baseball Game Youre now a baseball game point recorder. Given a list of strings, each string can be one of the 4 following types: Integer (one rounds score): Directly represents the number of points you get in this round. "+" (one rounds score): Represents that the points you get in this round are the sum of the last two valid rounds points. "D" (one rounds score): Represents that the points you get in this round are the doubled data of the last valid rounds points. "C" (an operation, which isnt a rounds score): Represents the last valid rounds points you get were invalid and should be removed. Each rounds operation is permanent and could have an impact on the round before and the round after. You need to return the sum of the points you could get in all the rounds. Example 1: Input: ["5","2","C","D","+"] Output: 30 Explanation: Round 1: You could get 5 points. The sum is: 5. Round 2: You could get 2 points. The sum is: 7. Operation 1: The round 2s data was invalid. The sum is: 5. Round 3: You could get 10 points (the round 2s data has been removed). The sum is: 15. Round 4: You could get 5 + 10 = 15 points. The sum is: 30. Example 2: Input: ["5","-2","4","C","D","9","+","+"] Output: 27 Explanation: Round 1: You could get 5 points. The sum is: 5. Round 2: You could get -2 points. The sum is: 3. Round 3: You could get 4 points. The sum is: 7. Operation 1: The round 3s data is invalid. The sum is: 3. Round 4: You could get -4 points (the round 3s data has been removed). The sum is: -1. Round 5: You could get 9 points. The sum is: 8. Round 6: You could get -4 + 9 = 5 points. The sum is 13. Round 7: You could get 9 + 5 = 14 points. The sum is 27. Solution: class Solution { public: int calPoints(vector<string>& ops) { int res = 0; int len = ops.size(); vector<int> data; for (int i = 0; i < len; i++){ if (ops[i] == "C"){ int tmp1 = data.back(); data.pop_back(); res -= tmp1; }else if(ops[i] == "D"){ int tmp0 = 2 * data.back(); data.push_back(tmp0); res += tmp0; }else if (ops[i] == "+"){ int tmp2 = data.back(); int tmp3 = data[data.size() - 2]; data.push_back(tmp2 + tmp3); res += (tmp2 + tmp3); }else{ int tmp = stoi(ops[i]); data.push_back(tmp); res += tmp; } } return res; } }; leetcode 3. Longest Substring Without Repeating Characters Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is "b", with the length of 1. Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring. 最笨的方法:o(n^2): class Solution { public: int lengthOfLongestSubstring(string s) { int res = 0, maxtmp; set<char> substr; int len = s.size(); if (len == 1){ res = 1; return res; } for (int i = 0; i < len; i++){ substr.insert(s[i]); maxtmp = 1; for (int j = i + 1; j < len; j++){ if (substr.find(s[j]) != substr.end()){ break; } else{ substr.insert(s[j]); maxtmp++; } } substr.clear(); res = max(res, maxtmp); } return res; } }; Leetcode 257. Binary Tree Paths Given a binary tree, return all root-to-leaf paths. For example, given the following binary tree: 1 / 2 3 5 All root-to-leaf paths are: ["1->2->5", "1->3"] /** * Definition for a binary tree node. * struct TreeNode { * int val; * TreeNode *left; * TreeNode *right; * TreeNode(int x) : val(x), left(NULL), right(NULL) {} * }; */ class Solution { public: void helper(TreeNode* root, string path, vector<string> &result){ if (!root->left && !root -> right){ // 註意這裏判斷的條件是葉子節點的時候 result.push_back(path); return; } if (root -> left){ helper(root -> left, path + "->" + to_string(root->left->val), result); } if (root -> right){ helper(root -> right, path + "->" + to_string(root->right->val), result); } } vector<string> binaryTreePaths(TreeNode* root) { vector<string> result; if (!root){ return result; } helper(root, to_string(root->val), result); return result; } };

一些leetcode算法題