Leetcode進階----學習(一)【兩數相加、無重複字元的最長字串】
①兩數相加
給定兩個非空連結串列來表示兩個非負整數。位數按照逆序方式儲存,它們的每個節點只儲存單個數字。將兩數相加返回一個新的連結串列。
你可以假設除了數字 0 之外,這兩個數字都不會以零開頭。
示例:
輸入:(2 -> 4 -> 3) + (5 -> 6 -> 4) 輸出:7 -> 0 -> 8 原因:342 + 465 = 807
1.此題解決思想比較簡單,直接設定一個進位carry,由於連結串列是按照逆序儲存的,計算兩數之和就可以直接從首節點開始計算求和,然後每次求得的和需要計算出該位的進位,即新進位carry = sum/10,在這裡需要建立一個新連結串列用來儲存求得的和(通過new建立)
class Solution { public: ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) { ListNode* dummyRoot = new ListNode(0); //建立新連結串列儲存求和資料 ListNode* p = dummyRoot; //定義指標p指向新連結串列 int carry = 0; while (l1 || l2) //只有同時為空時,才退出 { int x = l1 ? l1->val : 0; //判斷連結串列l1是否為空,不為空則取出資料 int y = l2 ? l2->val : 0; //判斷連結串列l2是否為空,不為空則取出資料 int sum = x + y + carry; //計算兩數之和 carry = sum/10; //計算新進位 p->next = new ListNode(sum%10); //建立新連結串列中的新節點 p = p->next; if (l1) //如果不為空,繼續遍歷 l1 = l1->next; if (l2) l2 = l2->next; } if (carry == 1) //判斷是否存在進位,存在則把1加到新連結串列中 p->next = new ListNode(1); return dummyRoot->next; } };
2.該題還有一種變形,即兩個數不是按照逆序存在連結串列中,而是正序,有興趣可以參考下Grandyang的部落格,具體做法有兩種,一種是將連結串列翻轉,然後使用上述的方法求和;另一種不採用翻轉連結串列,有點複雜,感興趣的同學可以自己去了解。。。
②無重複字元的最長字串
給定一個字串,找出不含有重複字元的最長子串的長度。
示例 1:
輸入: "abcabcbb"
輸出: 3
解釋: 無重複字元的最長子串是 "abc",其
長度為 3。
示例 2:
輸入: "bbbbb" 輸出: 1 解釋: 無重複字元的最長子串是"b"
,其長度為 1。
示例 3:
輸入: "pwwkew" 輸出: 3 解釋: 無重複字元的最長子串是"wke"
,其長度為 3。 請注意,答案必須是一個子串,"pwke"
是一個子序列 而不是子串。
1.使用set容器儲存字元,如果之前未出現則存入set中,如果出現相同字元則從上一個left開始刪除,刪除到重複字元為止,其中記錄下最大子串長度:
具體分析:
若字串為abbca
首先i=0,存入set,此時set中存有字元a,更新cnt為1
i=1,沒有相同,存入set,此時set中存有字元a、b,更新cnt為2
i=2,出現相同字元b,則從上一個left = 0開始刪除,刪除後set中無元素,此時st.size()為0
刪除過後i=2,此時set中沒有相同,存入b,st.size()為1,小於之前cnt,不更新
i=3,存入c,此時st.size()為2,不更新
i=4,存入a,此時st.size()為3,更新cnt為3,則此為最大長度,最大字串為bca
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int cnt = 0,left = 0,n = s.size();
unordered_set<char> st; //儲存出現的字元
int i = 0;
while (i < n)
{
if (!st.count(s[i])) //未出現相同字元,則將字元插入set中,並更新子串長度為當前最大
{
st.insert(s[i++]); //插入當前字元,下移一位
cnt = max(cnt, (int)st.size());
}
else
st.erase(s[left++]); //出現相同字元則從上一個left開始刪除,直到重複字元為止
}
return cnt;
}
};
2.使用hashmap來建立字元與其位置之間的聯絡,具體使用left標記重複字元的位置,根據該left得出最大長度:
具體分析:
若字串為abbca
根據該思路,首先建立聯絡
i=0:left為0,字元‘a'位置為1,res長度為1
i=1:left為0,字元’b‘位置為2,res長度為2
i=2:出現重複字元’b',此時更新left的位置,使其指向上一個‘b’出現的位置2,更新新‘b'的位置為3,更新res長度為1
i=3:left為2,字元‘c’位置為4,res長度為2
i=4:left為2,字元’a‘位置更新為5,res長度更新為3
返回3
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int res = 0, left = 0, i = 0, n = s.size();
unordered_map<char, int> m; //建立字元與其位置的聯絡
for (int i = 0; i < n; ++i) { //遍歷陣列,若出現重複字元則更新left的位置,使其指向重複字元
left = max(left, m[s[i]]);
m[s[i]] = i + 1;
res = max(res, i - left + 1); //根據left計算最大長度
}
return res;
}
};