leetcode笔记(python和c++实现)

手写卷积实现-python

def conv(data, k, stride, bias):
    row, col = data.shape
    krow, kcol = k.shape
    res = []
    for i in range(row-krow, stride):
        rowlist = []
        for j in range(col-kcol, stride):
            curdata = data[i:i+krow, j:j+kcol]
            rowlist.append(np.sum(np.multiply(curdata, k)) + bias)
        res.append(rowlist)
    return res

计算PSNR- python

def psnr(img1, img2):
    imgmse = np.mean((img1-img2)**2)
    if imgmse == 0:
        return 100
    return 20 * math.log10(255 / math.sqrt(imgmse))

1. 两数之和

class Solution:
    def twoSum(self, nums: List[int], target: int) -> List[int]:
        twoSumDic = dict()
        for i in range(len(nums)):
            if target-nums[i] in twoSumDic:
                return [twoSumDic[target-nums[i]], i]
            twoSumDic[nums[i]] = i
        return []
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        unordered_map<int, int> twoSumMap;
        int n = nums.size();
        for (int i = 0; i<n; i++){
            if (twoSumMap.find(target-nums[i]) != twoSumMap.end()){
                return {twoSumMap[target-nums[i]], i};
            }
            twoSumMap[nums[i]] = i;
        }
        return {};
    }
};

2. 两数相加+1

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    # def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
    #     flag = 0
    #     out = ListNode()
    #     tem = out
    #     while l1 or l2 or flag:
    #         if l1 and l2:
    #             tem.next = ListNode((l1.val + l2.val + flag) % 10)
    #             flag = (l1.val + l2.val + flag) // 10
    #             l1 = l1.next
    #             l2 = l2.next
    #         elif l1:
    #             tem.next = ListNode((l1.val + flag) % 10)
    #             flag = (l1.val + flag) // 10
    #             l1 = l1.next
    #         elif l2:
    #             tem.next = ListNode((l2.val + flag) % 10)
    #             flag = (l2.val + flag) // 10
    #             l2 = l2.next
    #         elif flag:
    #             tem.next = ListNode(flag)
    #             flag = 0
    #         tem = tem.next
    #     return out.next

    def addTwoNumbers(self, l1: Optional[ListNode], l2: Optional[ListNode]) -> Optional[ListNode]:
        out = tem = ListNode()
        R = 0
        while l1 or l2 or R:
            if l1:
                R += l1.val
                l1 = l1.next
            if l2:
                R += l2.val
                l2 = l2.next
            tem.next = ListNode(R % 10)
            R = R // 10
            tem = tem.next
        return out.next
       
       
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    // ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
    //     ListNode* out = new ListNode(0);
    //     ListNode* tem = out;
    //     int flag = 0;
    //     while (l1 || l2){
    //         if (l1 && l2){
    //             tem->next = new ListNode((l1->val + l2->val + flag) % 10);
    //             flag = (l1->val+ l2->val+flag) / 10;
    //             l1 = l1->next;
    //             l2 = l2->next;
    //         }else if (l1){
    //             tem->next = new ListNode((l1->val + flag) % 10);
    //             flag = (l1->val + flag) / 10;
    //             l1 = l1->next;
    //         }else if (l2){
    //             tem->next = new ListNode((l2->val + flag) % 10);
    //             flag = (l2->val + flag) / 10;
    //             l2 = l2->next;
    //         }
    //         tem = tem->next;
    //     }
    //     if (flag){
    //         tem->next = new ListNode(flag);
    //     }
    //     return out->next;
    // }

    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode* out = new ListNode();
        ListNode* tem = out;
        int R = 0;
        while (l1 or l2 or R){
            if (l1){
                R += l1->val;
                l1 = l1->next;
            }
            if (l2){
                R += l2->val;
                l2 = l2->next;
            }
            tem->next = new ListNode(R % 10);
            R = R / 10;
            tem = tem->next;
        }
        return out->next;
    }
};

3. 无重复字符的最长子串+1

class Solution: 
    def mystring(self, s):
        ans = 0
        subStr = ''
        for curs in s:
            for i in range(len(subStr)):
                if subStr[i] == curs:
                    subStr = subStr[i+1:]
                    break
            subStr += curs
            ans = max(ans, len(subStr))
        return ans

    def myset(self, s):
        setS = set()
        ans, left = 0, 0
        for i in range(len(s)):
            if s[i] in setS:
                while s[left] != s[i]:
                    setS.remove(s[left])
                    left +=1
                left +=1
            else:
                setS.add(s[i])
            ans = max(ans, i-left+1)
        return ans

    def mydic(self, s):
        ans, left = 0, 0
        dic = dict()
        for i in range(len(s)):
            if dic.get(s[i], 'no') != 'no':
                while s[left] != s[i]:
                    del dic[s[left]]
                    left += 1
                left += 1
            else:
                dic[s[i]] = 1
            ans = max(ans, i-left+1)
        return ans

    def mydeque(self, s):
        ans = 0
        que = collections.deque()
        for i in range(len(s)):
            while s[i] in que:
                que.popleft()
            que.append(s[i])
            ans = max(ans, len(que))
        return ans

    def lengthOfLongestSubstring(self, s: str) -> int:
        return self.mystring(s)
        # return self.myset(s)
        # return self.mydic(s)
        # return self.mydeque(s)
class Solution {
public:
    int mymax(int a, int b){
        if (a>=b) return a;
        return b;
    }
    int mystring(string s){
        int ans = 0;
        string subS;
        for (int j=0; j<s.size(); ++j){
            for (int i=0; i<subS.size(); ++i){
                if (s[j] == subS[i]){
                    subS = subS.substr(i+1, subS.size());
                    break;
                }
            }
            subS += s[j];
            ans = mymax(ans, subS.size());
        }
        return ans;
    }
    int myset(string s){
        int ans=0, left=0;
        unordered_set<char> setS;
        for (int i=0; i<s.size(); ++i){
            if (setS.find(s[i]) != setS.end()){
                while (s[left] != s[i]){
                    setS.erase(s[left]);
                    left += 1;
                }
                left += 1;
            }else{
                setS.emplace(s[i]);
            }
            ans = mymax(ans, i-left+1);
        }
        return ans;
    }
    int mymap(string s){
        int ans=0, left=0;
        unordered_map<char, int> mapS;
        for (int i=0; i<s.size(); ++i){
            if (mapS.find(s[i]) != mapS.end()){
                while (s[left] != s[i]){
                    mapS.erase(s[left]);
                    left += 1;
                }
                left += 1;
            }
            else{
                mapS[s[i]] = 1;
            ans = mymax(ans, i-left+1);
            }
        }
        return ans;
    }
    int mydeque(string s){
        int ans=0;
        deque<char> que;
        for (int i=0; i<s.size(); ++i){
            while (true){
                deque<char>::iterator it = find(que.begin(), que.end(), s[i]);
                if (it != que.end()){
                    que.pop_front();
                }else{
                    break;
                }
            }
            que.push_back(s[i]);
            ans = ans > que.size() ? ans:que.size();
        }
        return ans;
    }
    int lengthOfLongestSubstring(string s) {
        // return mystring(s);
        // return myset(s);
        // return mymap(s);
        return mydeque(s);
    }
};

5. 最长回文子串+1

5. 最长回文子串

class Solution:
    def longestPalindrome(self, s: str) -> str:
        begin, end, res, n = 0, 1, 0, len(s)
        def expend(i, j):
            while i > 0 and j < n and s[i] == s[j]:
                i -= 1
                j += 1
            return i, j
        for i in range(n):
            left1, right1 = expend(i, i)
            left2, right2 = expend(i, i+1)
            if end - begin < right1 - left1:
                begin, end = left1, right1
            if end - begin < right2 - left2:
                begin, end = left2, right2
        print(begin, end)
        return s[begin+1:end]
    
 class Solution:
    def longestPalindrome(self, s: str) -> str:
        ans = s[0]
        for i in range(1, len(s)):
            shift = 1
            while i-shift>=0 and i+shift<= len(s)-1 and s[i-shift]==s[i+shift]:
                shift += 1
            ans = s[i-shift+1: i+shift] if (shift-1)*2+1>len(ans) else ans

            if s[i] == s[i-1]:
                shift = 1
                while i-shift-1>=0 and i+shift <= len(s)-1 and s[i-shift-1] == s[i+shift]:
                    shift += 1
                ans = s[i-shift: i+shift] if shift*2>len(ans) else ans
        return ans
class Solution {
public:
    string longestPalindrome(string s) {
        string ans = s.substr(0, 1);
        int n = s.size();
        for (int i=1; i<n; ++i){
            int shift=1;
            while ((i-shift)>=0 && (i+shift)<= (n-1) && s[i-shift]==s[i+shift]){
                shift += 1;
            }
            ans = (shift-1)*2+1>ans.size() ? s.substr(i-shift+1, shift*2-1) : ans;

            if (s[i] == s[i-1]){
                int shift = 1;
                while ((i-1-shift)>=0 && (i+shift) <= (n-1) && s[i-1-shift]==s[i+shift]){
                    shift +=1;
                }
                ans = shift*2 > ans.size() ? s.substr(i-shift, shift*2) : ans;
            }
        }
        return ans;
    }
};

11. 盛最多水的容器+1

class Solution:
    def maxArea(self, height: List[int]) -> int:
        left, right = 0, len(height)-1
        ans = 0
        while left<right:
            ans = max(ans, min(height[left], height[right])*(right-left))
            if height[left] < height[right]:
                left +=1
            else:
                right -= 1
        return ans
class Solution {
public:
    int maxArea(vector<int>& height) {
        int left=0, right=height.size()-1, ans=0;
        while (left < right){
            ans = max(ans, min(height[left], height[right])*(right-left));
            if (height[left] > height[right]){
                right--;
            }
            else{
                left++;
            }
        }
        return ans;
    }
};

15. 三数之和+1

class Solution:
    def threeSum(self, nums: List[int]) -> List[List[int]]:
        nums.sort()
        ans = []
        n = len(nums)
        for i in range(n):
            if i>0 and nums[i]==nums[i-1]:
                continue
            if nums[i]>0:
                break
            left, right = i+1, n-1
            while left < right:
                if nums[right] < 0:
                    break
                curSum = nums[i] + nums[left] + nums[right]
                if curSum > 0:
                    right -=1
                elif curSum < 0:
                    left += 1
                else:
                    if left > i+1 and nums[left] == nums[left-1]:
                        left += 1
                        continue
                    ans.append([nums[i], nums[left], nums[right]])
                    left += 1
        return ans
class Solution {
public:
    vector<vector<int>> threeSum(vector<int>& nums) {
        vector<vector<int>> ans;
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for (int i=0; i<n; ++i){
            if (i>0 && nums[i]==nums[i-1]) continue;
            if (nums[i] > 0) break;
            int l = i+1, r = n-1;
            while (l < r){
                if (nums[r]<0) break;
                int curSum = nums[i] + nums[l] + nums[r];
                if (curSum>0){
                    --r;
                }
                else if (curSum<0){
                    ++l;
                }
                else{
                    if (l > i+1 && nums[l]==nums[l-1]){
                        ++l;
                        continue;
                    }
                    ans.push_back({nums[i], nums[l], nums[r]});
                    // if (ans.size()==0){
                    //     ans.push_back({nums[i], nums[l], nums[r]});
                    // }
                    // else{
                    //     vector lastans = ans.end()[-1];
                    //     if (lastans[0] != nums[i] || lastans[1] != nums[l] || lastans[2] !=nums[r]){
                    //         ans.push_back({nums[i], nums[l], nums[r]});
                    //     }
                    // }
                    ++l;
                }

            }
        }
        return ans;
    }
};

17. 电话号码的字母组合+1

class Solution:
    def letterCombinations(self, digits: str) -> List[str]:
        # # 队列
        # if len(digits) == 0:
        #     return []
        # letterTable = {'2':'abc','3':'def', '4':'ghi', '5':'jkl', '6':'mno',
        # '7':'pqrs', '8':'tuv', '9':'wxyz'}
        # ans = [""]
        # for i in range(len(digits)):
        #     curAnsNum = len(ans)
        #     while curAnsNum > 0:
        #         curAns, ans = ans[0], ans[1:]
        #         # curAns = ans.pop(0)
        #         curDigit = letterTable[digits[i]]
        #         for j in range(len(curDigit)):
        #             ans.append(curAns+curDigit[j])
        #         curAnsNum -= 1
        # return ans

        # 回溯
        if len(digits) == 0:
            return []
        letterTable = {'2':'abc','3':'def', '4':'ghi', '5':'jkl', '6':'mno',
        '7':'pqrs', '8':'tuv', '9':'wxyz'}
        ans = []
        def backtrack(path, chooses):
            if len(chooses) == 0:
                ans.append(path)
                return
            else:
                for choose in letterTable[chooses[0]]:
                    backtrack(path+choose, chooses[1:])
        backtrack('', digits)
        return ans
class Solution {
public:
    // vector ans;
    unordered_map<char, string> letterTable{{'2',"abc"},{'3',"def"},{'4',"ghi"} ,{'5',"jkl"} ,{'6',"mno"}, {'7',"pqrs"},{'8',"tuv"}, {'9',"wxyz"}};
    void backtrack(vector<string>&ans, string digits, string tem, int start, int target){
        if (start==target){
            ans.push_back(tem);
            return;
        }
        else{
            char curdigit = digits[start];
            for (int i=0; i<letterTable[curdigit].size(); ++i){
                char choose = letterTable[curdigit][i];
                tem.push_back(choose);
                backtrack(ans, digits, tem, start+1, target);
                tem.pop_back();
            }
        }
    }
    vector<string> letterCombinations(string digits) {
        vector<string> ans;
        if (digits.size()==0){
            return ans;
        }
        // // 队列
        // int n = digits.size();
        // ans = {""};
        // for (int i=0; i
        //     int count = ans.size();
        //     while (count > 0){
        //         string curansleft = ans[0];
        //         ans.erase(ans.begin());
        //         string curdigt = letterTable[digits[i]];
        //         for (int j=0; j
        //             ans.push_back(curansleft+curdigt[j]);
        //         }
        //         --count;
        //     }
        // }

        // 回溯
        // vector ans;
        string tem;
        backtrack(ans, digits, tem, 0, digits.size());
        return ans;
    }
};

19. 删除链表的倒数第 N 个结点

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def removeNthFromEnd(self, head: Optional[ListNode], n: int) -> Optional[ListNode]:
        pfirst = head
        psecond = head
        for i in range(n):
            pfirst = pfirst.next
        if pfirst:
            while pfirst.next:
                pfirst = pfirst.next
                psecond = psecond.next
            psecond.next = psecond.next.next
        else:
            head = head.next
        return head
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* pfirst = head;
        ListNode* psecond = head;
        for (int i=0; i<n; i++){
            pfirst = pfirst->next;
        }
        if (pfirst){
            while (pfirst->next){
                pfirst = pfirst->next;
                psecond = psecond->next;
            }
            psecond->next = psecond->next->next;
        }else{
            head = head->next;
        }
        return head;

    }
};

20. 有效的括号

class Solution:
    def isValid(self, s: str) -> bool:
        n = len(s)
        if n % 2 == 1:
            return False
        pairsTable = {')':'(', '}':'{',  ']':'['}
        leftTable = []
        for i in range(n):
            if s[i] in [')', '}', ']']:
                if len(leftTable) == 0:
                    return False
                else:
                    if leftTable.pop() != pairsTable[s[i]]:
                        return False
            else:
                leftTable.append(s[i])
        if len(leftTable)==0:
            return True
        else:
            return False
class Solution {
public:
    bool isValid(string s) {
        int n = s.size();
        if (1 == n%2){
            return false;
        }
        unordered_map<char, char> pair={
            {'}','{'},
            {']','['},
            {')','('}
        };
        stack<char> stk;
        for (char ch:s){
            if (pair.count(ch)){
                if (stk.empty() || stk.top() != pair[ch]){
                    return false;
                }
                stk.pop();
            }
            else{
                stk.push(ch);
            }
        }
        return stk.empty();
        }
};

21.合并两个有序链表(递归+迭代)

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
# class Solution:
#     def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
#         if list1 is None:
#             return list2
#         if list2 is None:
#             return list1
#         ret = ListNode(0)
#         tem = ret
#         while list1 and list2:
#             if list1.val <= list2.val:
#                 tem.next = list1
#                 list1 = list1.next
#             else:
#                 tem.next = list2
#                 list2 = list2.next
#             tem = tem.next
#         tem.next = list1 if list1 else list2
#         return ret.next


class Solution:
    def mergeTwoLists(self, list1: Optional[ListNode], list2: Optional[ListNode]) -> Optional[ListNode]:
        if list1 is None:
            return list2
        if list2 is None:
            return list1
        if list1.val <= list2.val:
            list1.next = self.mergeTwoLists(list1.next, list2)
            return list1
        else:
            list2.next = self.mergeTwoLists(list2.next, list1)
            return list2
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
// class Solution {
// public:
//     ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
//         ListNode* ret = new ListNode(-1);
//         ListNode* tem = ret;
//         if (list1 == nullptr){
//             return list2;
//         }
//         if (list2 == nullptr){
//             return list1;
//         }
//         while (list1 and list2){
//             if (list1->val <= list2->val){
//                 tem->next = list1;
//                 list1 = list1->next;
//             }
//             else{
//                 tem->next = list2;
//                 list2 = list2->next;
//             }
//             tem = tem->next;
//         }
//         tem->next = list1 == nullptr ? list2 :list1;
//         return ret->next;
        
//     }
// };

class Solution {
public:
    ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
        if (list1 == nullptr){
            return list2;
        }
        if (list2 == nullptr){
            return list1;
        }
        if (list1->val <= list2->val){
            list1->next = mergeTwoLists(list1->next, list2);
            return list1;
        }else{
            list2->next = mergeTwoLists(list1, list2->next);
            return list2;
        }

        
    }
};

22. 括号生成+1

class Solution:
    def generateParenthesis(self, n: int) -> List[str]:
        res = []
        def backtrack(s, left, right):
            if len(s) == n:
                res.append(s)
            if left<n:
                s += "("
                backtrack(s, left+1, right)
                s = s[:-1]
            if left>right:
                s += ")"
                backtrack(s,left,right+1)
                s = s[:-1]
        backtrack("",0,0)
        return res

class Solution:
    def backtrack(self, ans, tem, n, start, brackets):
        if start[0]==n and start[1]==n:
            ans.append(tem)
            return
        if start[0] > n or start[1] > n or start[0] < start[1]:
            return
        for j, s in enumerate(brackets):
            tem += s
            start[j%2] += 1
            self.backtrack(ans, tem, n, start, brackets)
            tem = tem[:-1]
            start[j%2] -= 1

    def generateParenthesis(self, n: int) -> List[str]:
        ans = []
        tem = ''
        self.backtrack(ans, tem, n, [0, 0], ['(', ')'])
        return ans
class Solution {
public:
    void backtrack(vector<string>& ans, string tem, int n, vector<int> &start){
        if (start[0] == n && start[1] == n){
            ans.push_back(tem);
            return;
        }
        if (start[0] > n || start[1] > n || start[0] < start[1]){
            return;
        }
        for (int i=0; i<2; i++){
            if (start[0]==start[1]){
                tem.push_back('(');
            }else if (start[0]>start[1]){
                tem.push_back(i==0 ? '(' : ')');
            }
            ++start[i];
            backtrack(ans, tem, n, start);
            tem.pop_back();
            --start[i];
        }
    }
    vector<string> generateParenthesis(int n) {
        vector<string> ans;
        string tem;
        vector<int> start{0, 0};
        backtrack(ans, tem, n, start);
        return ans;
    }
};

31. 下一个排列+1

class Solution:
    def reverse(self, nums, l, r):
        while l < r:
            nums[l], nums[r] = nums[r], nums[l]
            l += 1
            r -= 1

    def nextPermutation(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        n = len(nums)
        plarge = n-1
        for i in range(n-1, 0, -1):
            if nums[i] > nums[i-1]:
                break
            plarge -= 1
        if plarge != 0:
            ptem = n - 1
            while nums[ptem] <= nums[plarge-1]:
                ptem -= 1
            nums[ptem], nums[plarge-1] = nums[plarge-1], nums[ptem]
        self.reverse(nums, plarge, n-1)
class Solution {
private:
    void reverse(vector<int>& nums, int left, int right){
        while (left<right){
            int tem = nums[left];
            nums[left] = nums[right];
            nums[right] = tem;
            ++left;
            --right;
        }
    }
public:
    void nextPermutation(vector<int>& nums) {
        int n = nums.size();
        int plarge = n - 1;
        for (int i=n-1; i>0; --i){
            if (nums[i]<=nums[i-1]){
                --plarge;
            }else{
                break;
            }
        }
        if (plarge != 0){
            for (int i=n-1; i>0; --i){
                if (nums[plarge-1] < nums[i]){
                    int tem = nums[plarge-1];
                    nums[plarge-1] = nums[i];
                    nums[i] = tem;
                    break;
                }
            }
        }
        reverse(nums, plarge, n-1);
    }
};

611 有效三角形的个数

二分

class Solution:
    def triangleNumber(self, nums: List[int]) -> int:
        n, res = len(nums), 0
        if n<3:
            return 0
        nums.sort()
        print(nums)
        for i in range(n):
            for j in range(i+1, n):
                left, right, k = j+1, n-1, j
                while left <= right:
                    mid = (left + right) // 2
                    if nums[i] + nums[j] > nums[mid]:
                        k = mid
                        left = mid+1
                    else:
                        right = mid-1
                res += k - j
        return res

双指针

class Solution:
    def triangleNumber(self, nums: List[int]) -> int:
        res, n = 0, len(nums)
        nums.sort()
        print(nums)
        if n < 3:
            return 0
        for i in range(n):
            k = i+2
            for j in range(i+1, n):
                while k < n and nums[i] + nums[j] > nums[k]:
                    k += 1
                res += max(k-j-1, 0)
        return res

33. 搜索旋转排序数组+1

二分,判断哪边是有序的

class Solution:
    def bisection(self, nums, l, r, target):
        while l <= r:
            mid = (r-l)//2 + l
            if nums[mid] == target:
                return mid
            if nums[l] <= nums[mid]:
                if nums[l] <= target and target < nums[mid]:
                    l, r = l, mid-1
                else:
                    l, r = mid+1, r
            else:
                if nums[mid] < target and target <= nums[r]:
                    l, r = mid+1, r
                else:
                    l, r = l, mid-1
        return -1
    def search(self, nums: List[int], target: int) -> int:
        return self.bisection(nums, 0, len(nums)-1, target)
class Solution {
private:
    int bisection(vector<int>& nums, int target){
        int mid, l=0, r=nums.size()-1;
        while (l<=r){
            mid = (r-l) / 2 + l;
            if (nums[mid] ==  target){
                return mid;
            }
            if (nums[l] <= nums[mid]){
                if (nums[l] <= target && target < nums[mid]){
                    r = mid - 1;
                }else{
                    l = mid + 1;
                }
            }else{
                if (nums[mid]<target && target<= nums[r]){
                    l = mid + 1;
                }
                else{
                    r = mid -1 ;
                }
            }
        }
        return -1;
    }
public:
    int search(vector<int>& nums, int target) {
        return bisection(nums, target);
    }
};

34. 在排序数组中查找元素的第一个和最后一个位置+1

class Solution:
    def bisection(self, nums, target):
        l, r, mid = 0, len(nums)-1, inf
        findtarget = False
        while l <= r:
            mid = (r-l)//2+l
            if nums[mid] == target:
                findtarget = True
                break
            elif nums[mid] < target:
                l = mid + 1
            else:
                r = mid - 1
        if not findtarget:
            return [-1, -1]
        else:
            l, r = mid, mid
            while l>=1 and nums[l] == nums[l-1]:
                l -= 1
            while r <= len(nums)-2 and nums[r]==nums[r+1]:
                r += 1
            return [l, r]

    def searchRange(self, nums: List[int], target: int) -> List[int]:
        return self.bisection(nums, target)
class Solution {
private:
    vector<int> bisection(vector<int> &nums, int target){
        int l=0, r=nums.size()-1, findtarget=0, mid;
        while (l<=r){
            mid = (r-l) / 2 + l;
            if (nums[mid]==target){
                findtarget = 1;
                break;
            }else if(nums[l]<=target && target< nums[mid]){
                r = mid-1;
            }else{
                l = mid+1;
            }
        }
        if (findtarget){
            l = mid, r = mid;
            while (l>0 && nums[l]==nums[l-1]){
                --l;
            }
            while (r<nums.size()-1 && nums[r]==nums[r+1]){
                ++r;
            }
            return vector<int>{l, r};
        }else{
            return vector<int>{-1, -1};
        }

    }
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        return bisection(nums, target);

    }
};

39. 组合总和+1

输入: candidates = [2,3,6,7], target = 7
输出: [[7],[2,2,3]]

回溯,模板

res = []                      # 定义全局变量
backtrack(curres, choice):
    if 满足条件:
        res.append(curres)    # 增加当前合理的选择
    if 跳出界限:
        return                # 返回
    for i in choice:          # 做选择
        backtrack(curres + 选择, 剩余选择)
backtrack([], 题干的input)
return res
class Solution:
    def backtrack(self, ans, tem, candidates, start, target):
        if sum(tem)==target:
            ans.append(tem[:])
        if sum(tem)>target:
            return
        for i in range(start, len(candidates)):
            tem.append(candidates[i])
            self.backtrack(ans, tem, candidates, i, target)
            tem.pop()

    def combinationSum(self, candidates: List[int], target: int) -> List[List[int]]:
        ans = []
        self.backtrack(ans, [], candidates, 0, target)
        return ans
class Solution {
private:
    void backtrack(vector<vector<int>> &ans, vector<int> &tem, vector<int> &candidates, int start, int target, int temsum){
        if (temsum == target){
            ans.push_back(tem);
            return;
        }
        if (temsum > target){
            return;
        }
        for (int i=start; i<candidates.size(); ++i){
            tem.push_back(candidates[i]);
            temsum += candidates[i];
            backtrack(ans, tem, candidates, i, target, temsum);
            temsum -= tem.back();
            tem.pop_back();
            
        }
    }
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        vector<vector<int>> ans;
        vector<int> tem;
        backtrack(ans, tem, candidates, 0, target, 0);
        return ans;
        
    }
};

46. 全排列+1

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

回溯

class Solution:
    def permute(self, nums: List[int]) -> List[List[int]]:
        res = []
        n = len(nums)
        def backtrack(curres, choice):
            if len(curres) == n:
                res.append(curres)
                return
            for i in range(len(choice)):
                backtrack(curres + [choice[i]], choice[:i]+choice[i+1:])
        backtrack([], nums)
        return res
 
class Solution:
    def backtrack(self, ans, tem, chooses, target, visit):
        if len(tem) == target:
            ans.append(tem[:])
            return
        if len(tem) > target:
            return
        for i in range(len(chooses)):
            if visit[i] == 1:
                continue
            tem.append(chooses[i])
            visit[i] = 1
            self.backtrack(ans, tem, chooses, target, visit)
            tem.pop()
            visit[i] = 0

    def permute(self, nums: List[int]) -> List[List[int]]:
        ans = []
        visit = [0 for i in range(len(nums))]
        self.backtrack(ans, [], nums, len(nums), visit)
        return ans
class Solution {
private:
    void backtrack(vector<vector<int>>& ans, vector<int>& nums, vector<int>& tmp, vector<int>& visit, int target){
        if (tmp.size()==target){
            ans.push_back(tmp);
            return;
        }
        if (tmp.size() > target){return;}
        for (int i=0; i<nums.size(); ++i){
            if (visit[i] == 1){continue;}
            tmp.push_back(nums[i]);
            visit[i] = 1;
            backtrack(ans, nums, tmp, visit, target);
            tmp.pop_back();
            visit[i] = 0;
        }
    }
public:
    vector<vector<int>> permute(vector<int>& nums) {
        vector<vector<int>> ans;
        vector<int> tmp, visit(nums.size(), 0);
        backtrack(ans, nums, tmp, visit, nums.size());
        return ans;
    }
};

48. 旋转图像+1(顺时针旋转 90 度)

class Solution:
    def rotate(self, matrix: List[List[int]]) -> None:
        """
        Do not return anything, modify matrix in-place instead.
        """
        h, w = len(matrix), len(matrix[0])
        for i in range(h//2):
            for j in range(w):
                matrix[i][j], matrix[h-i-1][j] = matrix[h-i-1][j], matrix[i][j]
        for i in range(h-1):
            for j in range(i+1, w):
                matrix[i][j], matrix[j][i]= matrix[j][i], matrix[i][j]
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int h=matrix.size(), w=matrix[0].size();
        for (int i=0; i<h/2; ++i){
            for (int j=0; j<w; ++j){
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[h-1-i][j];
                matrix[h-1-i][j] = tmp;
            }
        }
        for (int i=0; i<h-1; ++i){
            for (int j=i+1; j<w; ++j){
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[j][i];
                matrix[j][i] = tmp;
            }
        }

    }
};

49. 字母异位词分组+1

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]
class Solution:
    def baseSort(self, strs):
        ans = dict()
        for str in strs:
            cur_key = "".join(sorted(str))
            if ans.get(cur_key, 0) != 0:
                ans[cur_key].append(str)
            else:
                ans[cur_key] = [str]
        return list(ans.values())
    
    def keyTable(self, strs):
        ans = collections.defaultdict(list)
        for str in strs:
            keyTable = [0] * 26
            for s in str:
                keyTable[ord(s)-ord('a')] += 1
            ans[tuple(keyTable)].append(str)
        return list(ans.values())


    def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
        # return self.baseSort(strs)
        return self.keyTable(strs)
class Solution {
public:
    vector<vector<string>> basesort(vector<string>& strs){
        unordered_map<string, vector<string>> mp;
        for (string str:strs){
            string curKey = str;
            sort(curKey.begin(), curKey.end());
            // mp[curKey].push_back(str);
            mp[curKey].emplace_back(str);
        }
        vector<vector<string>> ans;
        for (auto it=mp.begin(); it!=mp.end(); ++it){
            // ans.push_back(it->second);
            ans.emplace_back(it->second);
        }
        return ans;
    }
    vector<vector<string>> baseAscll(vector<string>& strs){
        vector<vector<string>> ans;
        unordered_map<string, vector<string>> mp;
        for (auto str:strs){
            // string curKey(26, 'NUL');
            string curKey(26, 'DEL');
            for (auto s:str){
                ++curKey[s-'a'];
            }
            mp[curKey].emplace_back(str);
        }
        for (auto c:mp){
            ans.emplace_back(c.second);
        }
        return ans;
    }
    vector<vector<string>> groupAnagrams(vector<string>& strs) {
        // return basesort(strs);
        return baseAscll(strs);

    }
};

53. 最大子数组和

class Solution:
    def baseTable(self, nums):
        ans = nums[0]
        table = [0] * len(nums)
        table[0] = ans
        for i in range(1, len(nums)):
            table[i] = max(table[i-1]+nums[i], nums[i])
            ans = max(ans, table[i])
        return ans

    def bisection(self, nums):
        n = len(nums)
        if n == 1:
            return nums[0]
        else:
            mid = len(nums) // 2
            max_left = self.bisection(nums[:mid])
            max_right = self.bisection(nums[mid:])
        max_mid = nums[mid]
        tem = 0
        max_l = tem
        for i in range(mid-1, -1, -1):
            tem += nums[i]
            max_l = max(max_l, tem)
        tem = 0
        max_r = tem
        for i in range(mid+1, len(nums)):
            tem += nums[i]
            max_r = max(max_r, tem)
        return max(max_left, max_right, max_l+max_r+max_mid)
        
    def maxSubArray(self, nums: List[int]) -> int:
        # return self.baseTable(nums)
        return self.bisection(nums)
class Solution {
private:
    int baseDP(vector<int>& nums){
        int ans=nums[0];
        // vector table(nums.size(), 0);
        // table[0] = ans;
        int preMax = ans;
        for (int i=1; i<nums.size(); ++i){
            // table[i] = max(table[i-1]+nums[i], nums[i]);
            preMax = max(preMax+nums[i], nums[i]);
            // ans = max(ans, table[i]);
            ans = max(ans, preMax);
        }
        return ans;
    }
    int bisection(vector<int>& nums){
        int n = nums.size();
        int mid = nums.size()/2;
        int max_left, max_right;
        if (n == 1){return nums[0];}
        else{
            vector<int> numsLeft(nums.begin(), nums.begin()+mid);
            vector<int> numsRight(nums.begin()+mid, nums.end());
            max_left = bisection(numsLeft);
            max_right = bisection(numsRight);
        }
        int max_mid = nums[mid];
        int max_l=0, tem=0;
        for (int i=mid-1; i>=0; --i){
            tem += nums[i];
            max_l = max(max_l, tem);
        }
        int max_r=0;
        tem=0;
        for (int i=mid+1; i<nums.size(); ++i){
            tem += nums[i];
            max_r = max(max_r, tem);
        }
        return max(max(max_left, max_right), max_l+max_r+max_mid);
    }
public:
    int maxSubArray(vector<int>& nums) {
        // return baseDP(nums);
        return bisection(nums);
    }
};

55. 跳跃游戏+1

输入:nums = [2,3,1,1,4]
输出:true
解释:可以先跳 1 步,从下标 0 到达下标 1, 然后再从下标 13 步到达最后一个下标。
class Solution:
    def canJump(self, nums: List[int]) -> bool:
        n = len(nums)
        curMaxIndex = 0
        for i in range(n):
            curMaxIndex = max(i + nums[i], curMaxIndex)
            if curMaxIndex >= n-1:
                return True
            if curMaxIndex == i:
                return False
class Solution {
public:
    bool canJump(vector<int>& nums) {
        int n = nums.size();
        int curMaxIndex = 0;
        for (int i=0; i<n; ++i){
            curMaxIndex = max(curMaxIndex, i+nums[i]);
            if (curMaxIndex >= n-1){
                return true;
            }
            if (curMaxIndex == i){
                return false;
            }
        }
        return true;
    }
};

56. 合并区间+1

输入:intervals = [[1,3],[2,6],[8,10],[15,18]]
输出:[[1,6],[8,10],[15,18]]
解释:区间 [1,3][2,6] 重叠, 将它们合并为 [1,6].
class Solution:
    def merge(self, intervals: List[List[int]]) -> List[List[int]]:
        intervals.sort()
        n = len(intervals)
        ans = [intervals[0]]
        for i in range(1, n):
            if intervals[i][0] <= ans[-1][1]:
                ans[-1][1] = max(ans[-1][1], intervals[i][1])
            else:
                ans.append(intervals[i])
        return ans
class Solution {
public:
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
        sort(intervals.begin(), intervals.end());
        int n = intervals.size();
        vector<vector<int>> ans={intervals[0]};
        for (int i=1; i<n; ++i){
            if (ans.back()[1]>= intervals[i][0]){
                ans.back()[1] = max(ans.back()[1], intervals[i][1]);
            }
            else{
                ans.push_back(intervals[i]);
            }
        }
        return ans;
    }
};

62. 不同路径+1
不同路径

输入:m = 3, n = 7
输出:28
class Solution:
    def uniquePaths(self, m: int, n: int) -> int:
        table = [[1 for i in range(n)] for j in range(m)]
        for i in range(1, m):
            for j in range(1, n):
                table[i][j] = table[i-1][j] + table[i][j-1]
        return table[m-1][n-1]
class Solution {
public:
    int uniquePaths(int m, int n) {
        vector<vector<int>> table(m, vector<int>(n, 1));
        for (int i=1; i<m; ++i){
            for (int j=1; j<n; ++j){
                table[i][j] = table[i-1][j]+table[i][j-1];
            }
        }
        return table[m-1][n-1];

    }
};

64. 最小路径和+1
最小路径和

输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 13111 的总和最小。
class Solution:
    def minPathSum(self, grid: List[List[int]]) -> int:
        m, n = len(grid), len(grid[0])
        DP = [[0 for i in range(n)] for j in range(m)]
        DP[0][0] = grid[0][0]
        for i in range(1, n):
            DP[0][i] = DP[0][i-1] + grid[0][i]
        for i in range(1, m):
            DP[i][0] = DP[i-1][0] + grid[i][0]
        for i in range(1, m):
            for j in range(1, n):
                DP[i][j] = min(DP[i-1][j], DP[i][j-1]) + grid[i][j]
        return DP[m-1][n-1]
class Solution {
public:
    int minPathSum(vector<vector<int>>& grid) {
        int m=grid.size(), n=grid[0].size();
        vector<vector<int>> DP(m, vector<int>(n));
        DP[0][0] = grid[0][0];
        for (int i=1; i<n; ++i){
            DP[0][i] = DP[0][i-1] + grid[0][i];
        }
        for (int i=1; i<m; ++i){
            DP[i][0] = DP[i-1][0] + grid[i][0];
        }
        for (int i=1; i<m; ++i){
            for (int j=1; j<n; ++j){
                DP[i][j] = min(DP[i-1][j], DP[i][j-1]) + grid[i][j];
            }
        }
        return DP[m-1][n-1];
    }
};

70. 爬楼梯

# class Solution:
#     def climbStairs(self, n: int) -> int:
#         f, s = 1, 2
#         if n == 1 or n == 2:
#             return n
#         while n-2>0:
#             f, s = s, f+s
#             n -= 1
#         return s
    
# class Solution:
#     def climbStairs(self, n: int) -> int:
#         if n == 1 or n == 2:
#             return n
#         dp = [0 for _ in range(n)]
#         dp[0] = 1
#         dp[1] = 2
#         for i in range(2, n):
#             dp[i] = dp[i-1] + dp[i-2]
#         return dp[n-1]


class Solution:
    def climbStairs(self, n: int) -> int:
        @lru_cache
        def dfs(n):
            if n == 1 or n == 2:
                return n
            return dfs(n-1) + dfs(n-2)
        return dfs(n)
// class Solution {
// public:
//     int climbStairs(int n) {
//         int f = 1, s = 2, t = 3;
//         if (1==n || 2==n ||3==n){
//             return n;
//         }
//         for (int i = 3; i
//             f = s;
//             s = t;
//             t = f + s;
//         }
//         return t;

//     }
// };

class Solution {
public:
    int climbStairs(int n) {
        if (1==n || 2==n ||3==n){
            return n;
        }
        int dp[46] = {0, 1, 2, 3};
        for (int i=4; i<n+1; ++i){
            dp[i] = dp[i-1] + dp[i-2];
        }
        return dp[n];

    }
};

// 超出时间限制
// class Solution {
// public:
//     int climbStairs(int n) {
//         if (1==n || 2==n ||3==n){
//             return n;
//         }
//         return climbStairs(n-1)+climbStairs(n-2);
//     }
// };

75. 颜色分类+1
颜色分类

输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
class Solution:
    def sortColors(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        l, r = 0, len(nums)-1
        start = 0
        while start<=r:
            if nums[start] == 0:
                nums[start], nums[l] = nums[l], nums[start]
                l += 1
                start += 1
            elif nums[start] == 2:
                nums[start], nums[r] = nums[r], nums[start]
                r -= 1
            else:
                start += 1
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int l=0, r=nums.size()-1, start=0;
        while (start<=r){
            if (nums[start]==0){
                int tem = nums[start];
                nums[start] = nums[l];
                nums[l] = tem;
                ++start;
                ++l;
            }
            else if(nums[start] == 2){
                int tem = nums[start];
                nums[start] = nums[r];
                nums[r] = tem;
                --r;
            }
            else{
                ++start;
            }
        }
    }
};

78. 子集

输入:nums = [1,2,3]
输出:[[],[1],[2],[1,2],[3],[1,3],[2,3],[1,2,3]]
class Solution:
    def subsets(self, nums: List[int]) -> List[List[int]]:
        res = [[]]
        for i in nums:
            stack = res
            for j in range(len(stack)):
                res.append(stack[j] + [i])
        return res

79. 单词搜索

给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中,返回 true ;否则,返回 false 。
class Solution:
    def exist(self, board: List[List[str]], word: str) -> bool:
        res = [False]
        n = len(word)
        row, col = len(board), len(board[0])
        def backtrack(i, j, index):
            if index == n-1:
                res[0] = True
                return
            table.add((i,j))
            for temi, temj in [[i+1,j], [i-1,j], [i,j+1], [i,j-1]]:
                if 0 <= temi < row and 0 <= temj < col and board[temi][temj] == word[index+1]:
                    if (temi, temj) not in table:
                        backtrack(temi, temj, index+1)
            table.remove((i,j))

        table = set()
        for i in range(row):
            for j in range(col):
                if board[i][j] == word[0]:
                    backtrack(i, j, 0)
        return res[0]

94. 二叉树的中序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
# class Solution:
#     def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
#         def dfs(curRoot, curList):
#             if curRoot == None:
#                 return curList
#             dfs(curRoot.left, curList)
#             curList.append(curRoot.val)
#             dfs(curRoot.right, curList)
#         out = []
#         dfs(root, out)
#         return out

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        stk = []
        out = []
        while root or len(stk)!=0:
            while root:
                stk.append(root)
                root = root.left
            root = stk.pop()
            out.append(root.val)
            root = root.right
        return out
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
// class Solution {
// public:
//     void dfs(TreeNode* root, vector& List){
//         if (!root){
//             return ;
//         }
//         dfs(root->left, List);
//         List.push_back(root->val);
//         dfs(root->right, List);
//     }
//     vector inorderTraversal(TreeNode* root) {
//         vector out;
//         dfs(root, out);
//         return out;
//     }
// };


class Solution {
public:
    vector<int> inorderTraversal(TreeNode* root) {
        vector<int> out;
        stack<TreeNode*> stk;
        while (root!=nullptr || !stk.empty()){
            while (root != nullptr){
                stk.push(root);
                root = root->left;
            }
            root = stk.top();
            stk.pop();
            out.push_back(root->val);
            root= root->right;
        }
        return out;
    }
};

96. 不同的二叉搜索树

给你一个整数 n ,求恰由 n 个节点组成且节点值从 1 到 n 互不相同的 二叉搜索树 有多少种?返回满足题意的二叉搜索树的种数。
class Solution:
    def numTrees(self, n: int) -> int:
        table = [1] + [0] * (n)
        for i in range(1, n+1):
            for j in range(i):
                table[i] += table[j] * table[i-j-1]
        return table[n]

98. 验证二叉搜索树

给定一个二叉树,判断其是否是一个有效的二叉搜索树。

假设一个二叉搜索树具有如下特征:

节点的左子树只包含小于当前节点的数。
节点的右子树只包含大于当前节点的数。
所有左子树和右子树自身必须也是二叉搜索树。

中序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isValidBST(self, root: TreeNode) -> bool:
        res = [True]
        pre = [-inf]
        def leftrootright(root):
            if not root:
                return
            leftrootright(root.left)
            val = root.val
            if val <= pre[0]:
                res[0] = False
                return 
            pre[0] = val
            leftrootright(root.right)
        leftrootright(root)
        return res[0]

101. 对称二叉树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
# class Solution:
#     def isSymmetric(self, root: Optional[TreeNode]) -> bool:
#         def check(l, r):
#             if l is None and r is None:
#                 return True
#             if l is None or r is None:
#                 return False
#             return l.val == r.val and check(l.right, r.left) and check(l.left, r.right)
#         return check(root.left, root.right)

class Solution:
    def isSymmetric(self, root: Optional[TreeNode]) -> bool:
        def check(l, r):
            stk = [l, r]
            while len(stk):
                pre = stk.pop(0)
                nex = stk.pop(0)
                if pre is None and nex is None:
                    continue
                if pre is None or nex is None or  pre.val != nex.val:
                    return False
                stk.append(pre.left)
                stk.append(nex.right)

                stk.append(pre.right)
                stk.append(nex.left)
            return True
        return check(root, root)
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
// class Solution {
// public:
//     bool check(TreeNode* L, TreeNode* R){
//         if (!L && !R){
//             return true;
//         }
//         if (!L || !R){
//             return false;
//         }
//         return L->val==R->val && check(L->left, R->right) && check(L->right, R->left);
//     }
//     bool isSymmetric(TreeNode* root) {
//         return check(root, root);
//     }
// };


class Solution {
public:
    bool check(TreeNode* L, TreeNode* R){
        queue<TreeNode*> q;
        q.push(L);
        q.push(R);
        while (!q.empty()){
            L = q.front(); q.pop();
            R = q.front(); q.pop();
            if (!L && !R){
                continue;
            }
            if (!L || !R || L->val!=R->val){
                return false;
            }

            q.push(L->left); q.push(R->right);
            q.push(L->right); q.push(R->left);

        }
        return true;
    }
    bool isSymmetric(TreeNode* root) {
        return check(root, root);
    }
};

102. 二叉树的层序遍历

给你一个二叉树,请你返回其按 层序遍历 得到的节点值。 (即逐层地,从左到右访问所有节点)。
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res = [[]]
        if not root:
            return []
        stack = [root, "flag"]
        while stack != ["flag"]:
            tem = stack.pop(0)
            if tem == "flag":
                res.append([])
                stack.append("flag")
            else:
                res[-1].append(tem.val)
                if tem.left:
                    stack.append(tem.left)
                if tem.right:
                    stack.append(tem.right)
        return res

104. 二叉树的最大深度

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
# 前序遍历
# class Solution:
#     def maxDepth(self, root: Optional[TreeNode]) -> int:
#         def dfs(root, cur, out):
#             if root is None:
#                 out[0] = max(cur, out[0])
#                 return
#             dfs(root.left, cur+1, out)
#             dfs(root.right, cur+1, out)
#         out = [0]
#         dfs(root, 0, out)
#         return out[0]
# dfs
# class Solution:
#     def maxDepth(self, root: Optional[TreeNode]) -> int:
#         if root is None: return 0
#         L = self.maxDepth(root.left)
#         R = self.maxDepth(root.right)
#         return max(L, R) + 1
# bfs
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if root is None: return 0
        stk = [root]
        out = 0
        while stk:
            n = len(stk)
            for i in range(n):
                curRoot = stk.pop(0)
                if curRoot.left:
                    stk.append(curRoot.left)
                if curRoot.right:
                    stk.append(curRoot.right)
            out += 1
        return out
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */

// //  前序遍历
// class Solution {
// public:
//     void def(TreeNode* root, int cur, int out[]){
//         if (!root){
//             if (cur > out[0]){
//                 out[0] = cur;
//             }
//             return;
//         }
//         def(root->left, cur+1, out);
//         def(root->right, cur+1, out);
//     }
//     int maxDepth(TreeNode* root) {
//         int ret[1] = {0};
//         def(root, 0, ret);
//         return ret[0];
//     }
// };

// //  dfs
// class Solution {
// public:
//     int mymax(int L, int R){
//         if (L > R){
//             return L;
//         }else{
//             return R;
//         }
//     }
//     int maxDepth(TreeNode* root) {
//         if (!root){
//             return 0;
//         }
//         int L = maxDepth(root->left);
//         int R = maxDepth(root->right);
//         return mymax(L, R) + 1;
//     }
// };


//  bfs
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if (!root){return 0;}
        queue<TreeNode*> q;
        q.push(root);
        int out = 0;
        while (!q.empty()){
            int n = q.size();
            for (int j=0; j<n; ++j){
                TreeNode* curRoot = q.front();
                q.pop();
                if (curRoot->left){
                    q.push(curRoot->left);
                }
                if (curRoot->right){
                    q.push(curRoot->right);
                }
            }
            out += 1;
        }
        return out;
    }
};

105. 从前序与中序遍历序列构造二叉树

给定一棵树的前序遍历 preorder 与中序遍历  inorder。请构造二叉树并返回其根节点。
Input: preorder = [3,9,20,15,7], inorder = [9,3,15,20,7]
Output: [3,9,20,null,null,15,7]
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def buildTree(self, preorder: List[int], inorder: List[int]) -> TreeNode:
        if not preorder:
            return
        root = TreeNode(preorder[0])
        inorderroot = inorder.index(preorder[0])
        root.left = self.buildTree(preorder[1:inorderroot+1], inorder[:inorderroot])
        root.right = self.buildTree(preorder[inorderroot+1:], inorder[inorderroot+1:])
        return root

114. 二叉树展开为链表

给你二叉树的根结点 root ,请你将它展开为一个单链表:

展开后的单链表应该同样使用 TreeNode ,其中 right 子指针指向链表中下一个结点,而左子指针始终为 null 。
展开后的单链表应该与二叉树 先序遍历 顺序相同。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def flatten(self, root: TreeNode) -> None:
        """
        Do not return anything, modify root in-place instead.
        """
        while root:
            temright = root.right
            root.right = root.left
            root.left = None
            cur = root
            while cur.right:
                cur = cur.right
            cur.right = temright
            root = root.right

121. 买卖股票的最佳时机

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        temMin, Out = inf, 0
        for i in range(len(prices)):
            curPrice = prices[i]
            if curPrice < temMin:
                temMin = curPrice
            else:
                Out = max(Out, curPrice-temMin)
        return Out
class Solution {
public:
    int maxProfit(vector<int>& prices) {
        int temMin = INT_MAX;
        int out = 0;
        for (int price:prices){
            if (price < temMin){
                temMin = price;
            }
            else{
                out = max(out, price-temMin);
            }
        }
        return out;
    }
};

128. 最长连续序列

输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4
class Solution:
    def longestConsecutive(self, nums: List[int]) -> int:
        nums.sort()
        if not nums:
            return 0
        n = len(nums)
        table = [1] * n
        for i in range(1, n):
            if nums[i] == nums[i-1]+1:
                table[i] = table[i-1] + 1
            if nums[i] == nums[i-1]:
                table[i] = table[i-1]
        return max(table)

136. 只出现一次的数字

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        out = 0
        for i in range(len(nums)):
            out = out ^ nums[i]
        return out
class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int out = 0;
        for (int num:nums){
            out = out ^ num;
        }
        return out;
    }
};

139. 单词拆分

输入: s = "leetcode", wordDict = ["leet", "code"]
输出: true
解释: 返回 true 因为 "leetcode" 可以被拆分成 "leet code"

动态规划。用回溯超时

class Solution:
    def wordBreak(self, s: str, wordDict: List[str]) -> bool:
        n = len(s)
        table = [True] + [False] * n
        for i in range(1, n+1):
            for c in wordDict:
                if len(c)<=i:
                    if table[i-len(c)] and c == s[i-len(c):i]:
                        table[i] = True
        return table[n]

141. 环形链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def hasCycle(self, head: Optional[ListNode]) -> bool:
        if head is None:
            return False
        fastP = head
        slowP = head
        while fastP.next and fastP.next.next:
            fastP = fastP.next.next
            slowP = slowP.next
            if fastP == slowP:
                return True
        return False
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        if (!head){
            return false;
        }
        while (fast->next and fast->next->next){
            fast = fast->next->next;
            slow = slow->next;
            if (fast == slow){
                return true;
            }
        }
        return false;
    }
};

142. 环形链表 II

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。注意,pos 仅仅是用于标识环的情况,并不会作为参数传递到函数中。

说明:不允许修改给定的链表。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def detectCycle(self, head: ListNode) -> ListNode:
        fast = head
        slow = head
        flag = False
        if not head:
            return None
        while fast.next and fast.next.next:
            fast = fast.next.next
            slow = slow.next
            if fast == slow:
                flag = True
                break
        if flag:
            cur = head
            fast = head
            while fast != slow:
                fast = fast.next
                slow = slow.next
            return fast
        else:
            return None

146. LRU 缓存机制

实现 LRUCache 类:

LRUCache(int capacity) 以正整数作为容量 capacity 初始化 LRU 缓存
int get(int key) 如果关键字 key 存在于缓存中,则返回关键字的值,否则返回 -1 。
void put(int key, int value) 如果关键字已经存在,则变更其数据值;如果关键字不存在,则插入该组「关键字-值」。当缓存容量达到上限时,它应该在写入新数据之前删除最久未使用的数据值,从而为新的数据值留出空间。
class LRUCache:

    def __init__(self, capacity: int):
        self.cap = capacity
        self.LRU = collections.OrderedDict()

    def get(self, key: int) -> int:
        if self.LRU.get(key, "flag") != "flag":
            self.LRU.move_to_end(key, last = True)
            return self.LRU.get(key, False)
        else:
            return -1

    def put(self, key: int, value: int) -> None:
        if self.LRU.get(key, "flag") != "flag":
            self.LRU[key] = value
            self.LRU.move_to_end(key, last = True)
        else:
            if len(self.LRU) == self.cap:
                self.LRU.popitem(last = False)
            self.LRU[key] = value

148. 排序链表{多看看}

给你链表的头结点 head ,请将其按 升序 排列并返回 排序后的链表 。
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def sortList(self, head: ListNode) -> ListNode:
        def mergeList(List1, List2):
            cur = ListNode()
            res = cur
            while List1 and List2:
                if List1.val < List2.val:
                    cur.next = List1
                    List1 = List1.next
                else:
                    cur.next = List2
                    List2 = List2.next
                cur = cur.next
            cur.next = List1 if List1 else List2
            return res.next
        
        if not head or not head.next:
            return head
        fast, slow = head.next, head
        while fast and fast.next:
            fast = fast.next.next
            slow = slow.next
        rightList = slow.next
        slow.next = None
        left, right = self.sortList(head), self.sortList(rightList)
        return mergeList(left, right)

152. 乘积最大子数组

给你一个整数数组 nums ,请你找出数组中乘积最大的连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积
输入: [2,3,-2,4]
输出: 6
解释: 子数组 [2,3] 有最大乘积 6
class Solution:
    def maxProduct(self, nums: List[int]) -> int:
        res, temmax, temmin = nums[0], nums[0], nums[0]
        n = len(nums)
        for i in range(1, n):
            temmax, temmin = max(nums[i], temmin*nums[i], temmax*nums[i]), min(nums[i], temmin*nums[i], temmax*nums[i])
            res = max(res, temmax)
        return res

160. 相交链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None

class Solution:
    def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
        tableA = []
        while headA:
            tableA.append(headA)
            headA = headA.next
        while headB:
            if headB in tableA:
                return headB
            headB = headB.next
        return None

# class Solution:
#     def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
#         if headB is None or headA is None:
#             return None
#         pa = headA
#         pb = headB
#         while pa != pb:
#             pa = pa.next if pa else headB
#             pb = pb.next if pb else headA
#         return pa
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
// class Solution {
// public:
//     ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//         unordered_set table;
//         ListNode *tema = headA;
//         while (tema != nullptr){
//             table.insert(tema);
//             tema = tema->next;
//         }
//         ListNode *temb = headB;
//         while (temb != nullptr){
//             if (table.count(temb)){
//                 return temb;
//             }
//             temb = temb->next;
//         }
//         return nullptr;
//     }
// };


class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        if (headA == nullptr || headB == nullptr){return nullptr;}
        ListNode *tema = headA;
        ListNode *temb = headB;
        while (tema != temb){
            tema = tema == nullptr ? headB:tema->next;
            temb = temb == nullptr ? headA:temb->next;
        }
        return temb;
    }
};

169. 多数元素

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        # # 1 排序
        # numsSorted = sorted(nums)
        # return numsSorted[(len(nums)//2)]

        # # 2 字典
        # keyTable, maj, majn = dict(), 0, 0
        # for num in nums:
        #     if keyTable.get(num, 'no') != 'no':
        #         keyTable[num] += 1
        #     else:
        #         keyTable[num] = 1
        #     if keyTable[num] > majn:
        #         maj = num
        #         majn = keyTable[num]
        # return maj

        # # 3 随机化
        # majn = len(nums)//2
        # while True:
        #     curN = random.choice(nums)
        #     if sum(1 for i in nums if i==curN) > majn:
        #         return curN

        # # 4 分治
        # def DAC(l, r):
        #     if l == r:
        #         return nums[l]
        #     mid = (r-l) // 2 + l
        #     majL = DAC(l, mid)
        #     majR = DAC(mid+1, r)
        #     if majL == majR:
        #         return majL
        #     majLN = sum(1 for i in range(l, r+1) if nums[i] == majL)
        #     majNR = sum(1 for i in range(l, r+1) if nums[i] == majR)
        #     return majL if majLN > majNR else majR
        # return DAC(0, len(nums)-1)

        # 5 投票
        maj, count = 0, 0
        for num in nums:
            if count == 0:
                maj = num
            count += 1 if num == maj else -1
        return maj
class Solution {
public:
    // int dac(vector& nums, int l, int r){
    //     if (l == r){
    //         return nums[l];
    //     }
    //     int mid = (r-l)/2 +l;
    //     int majL = dac(nums, l, mid);
    //     int majR = dac(nums, mid+1, r);
    //     if (majL == majR){
    //         return majL;
    //     }
    //     int majLN = 0, majRN = 0;
    //     for (int i = l; i<=r; ++i){
    //         if (majL == nums[i]){
    //             ++majLN;
    //         }
    //         if (majR == nums[i]){
    //             ++majRN;
    //         } 
    //     }
    //     return majLN > majRN ? majL:majR;
    // }
    int majorityElement(vector<int>& nums) {
        // // 1 排序
        // sort(nums.begin(), nums.end());
        // return nums[nums.size()/2];

        // // 2 字典
        // unordered_map keyTable;
        // int maj = 0, majn = 0;
        // for (int num:nums){
        //     ++keyTable[num];
        //     if (keyTable[num] > majn){
        //         maj = num;
        //         majn = keyTable[num];
        //     }
        // }
        // return maj;

        // // 3 随机化
        // int majn = nums.size()/2;
        // while (true){
        //     int curMaj = nums[rand() % nums.size()];
        //     int curMajN = 0;
        //     for (int num:nums){
        //         if (curMaj == num){
        //             ++curMajN;
        //         }
        //         if (curMajN > majn){
        //                 return curMaj;
        //         }
        //     }
        // }

        // // 4 分治
        // return dac(nums, 0, nums.size()-1);

        // 5 投票
        int maj = 0, majn = 0;
        for (int num:nums){
            if (majn == 0){
                maj = num;
            }
            if (maj == num){
                ++majn;
            }
            else{
                --majn;
            }
        }
        return maj;




    }
};

198. 打家劫舍

输入:[1,2,3,1]
输出:4
解释:偷窃 1 号房屋 (金额 = 1) ,然后偷窃 3 号房屋 (金额 = 3)。
     偷窃到的最高金额 = 1 + 3 = 4
class Solution:
    def rob(self, nums: List[int]) -> int:
        n = len(nums)
        table = [0] * n
        if n == 1:
            return nums[0]
        table[0], table[1] = nums[0], max(nums[0], nums[1])
        for i in range(2, n):
            table[i] = max(table[i-2]+nums[i], table[i-1])
        return table[-1]

200. 岛屿数量

给你一个由 '1'(陆地)和 '0'(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。
class Solution:
    def numIslands(self, grid: List[List[str]]) -> int:
        res = [0]
        def backtrack(i, j):
            # if grid[i][j] == "0":
            #     return
            # table.add((i,j))
            grid[i][j] = "0"
            for temi, temj in [[i+1, j], [i-1, j], [i, j+1], [i, j-1]]:
                if 0 <= temi < row and 0 <= temj < col and grid[temi][temj] == "1":
                    # if (temi, temj) not in table:
                        backtrack(temi, temj)
            # table.remove((i,j))

        
        # table = set()
        row, col = len(grid), len(grid[0])
        for i in range(row):
            for j in range(col):
                if grid[i][j] == "1":
                    backtrack(i, j)
                    res[0] += 1
        return res[0]

206. 反转链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def reverseList(self, head: Optional[ListNode]) -> Optional[ListNode]:
        tem = head
        out = ListNode().next
        while tem:
            tem = head.next
            head.next = out
            out = head
            head = tem
        return out
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* tmp = head;
        ListNode* out = nullptr;
        while (head!=nullptr){
            tmp = head->next;
            head->next = out;
            out = head;
            head = tmp;
        }
        return out;
    }
};

207. 课程表

你这个学期必须选修 numCourses 门课程,记为 0 到 numCourses - 1 。

在选修某些课程之前需要一些先修课程。 先修课程按数组 prerequisites 给出,其中 prerequisites[i] = [ai, bi] ,表示如果要学习课程 ai 则 必须 先学习课程  bi 。

例如,先修课程对 [0, 1] 表示:想要学习课程 0 ,你需要先完成课程 1 。
请你判断是否可能完成所有课程的学习?如果可以,返回 true ;否则,返回 false 。
class Solution:
    def canFinish(self, numCourses: int, prerequisites: List[List[int]]) -> bool:
        table = [0] * numCourses
        learnDic = {}
        for c in prerequisites:
            learnDic[c[1]] = learnDic.get(c[1], []) + [c[0]]
            table[c[0]] += 1

        learnNow = [x for x in range(numCourses) if table[x] == 0]

        while learnNow:
            # print(learnNow)
            curlearn = learnNow.pop()
            for iflearn in learnDic.get(curlearn, []):
                table[iflearn] -= 1
                if table[iflearn] == 0:
                    learnNow.append(iflearn)
        return max(table) == 0

215. 数组中的第K个最大元素

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
import random
class Solution:
    def findKthLargest(self, nums: List[int], k: int) -> int:
        def outindex(left, right):
            randomindex = random.randint(left, right)
            nums[randomindex], nums[left] = nums[left], nums[randomindex]
            flag = nums[left]
            left += 1
            while left <= right:
                if nums[left] >= flag:
                    nums[left-1] = nums[left]
                    left += 1
                else:
                    nums[left], nums[right] = nums[right], nums[left] 
                    right -= 1
            nums[left-1] = flag
            return left-1     # 注意要-1, 才是falg的索引

        left, right, index = 0, len(nums)-1, 0
        while left <= right:
            index = outindex(left, right)
            if index == k-1:
                return nums[index]
            elif index > k-1:
                right = index - 1 
            else:
                left = index + 1

221. 最大正方形

在一个由 '0''1' 组成的二维矩阵内,找到只包含 '1' 的最大正方形,并返回其面积。
class Solution:
    def maximalSquare(self, matrix: List[List[str]]) -> int:
        m, n = len(matrix), len(matrix[0])
        table = [[0]*n for _ in range(m)]
        for i in range(m):
            if matrix[i][0] == "1":
                table[i][0] = 1
        for j in range(n):
            if matrix[0][j] == "1":
                table[0][j] = 1

        for i in range(1, m):
            for j in range(1, n):
                if matrix[i][j] == "1":
                    table[i][j] = min(table[i-1][j-1], table[i-1][j], table[i][j-1]) + 1
        s = max([max(x) for x in table])
        return s*s

226. 翻转二叉树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def dfs(self, root):
        if root is None:
            return root
        tem = root.left
        root.left = root.right
        root.right = tem
        self.dfs(root.left)
        self.dfs(root.right)
        return root
        
    def bfs(self, root):
        que = [root]
        while que:
            curRoot= que.pop(0)
            if curRoot.left is None and curRoot.right is None:
                continue
            tem = curRoot.left
            curRoot.left = curRoot.right
            curRoot.right = tem
            if curRoot.left is not None:
                que.append(curRoot.left)
            if curRoot.right is not None:
                que.append(curRoot.right)
        return root

    def rec(self, root):
        if root is None:
            return root
        L = self.rec(root.left)
        R = self.rec(root.right)
        root.left, root.right = R, L
        return root

    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root is None:
            return root
        # # 1 dfs
        # return self.dfs(root)

        # 2 bfs
        return self.bfs(root)

        # # 3 rec
        # return self.rec(root)
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* rec(TreeNode* root){
        if (!root) return root;
        TreeNode* L = rec(root->left);
        TreeNode* R = rec(root->right);
        root->left = R;
        root->right = L;
        return root;
    }
    TreeNode* dfs(TreeNode* root){
        if (!root) return root;
        TreeNode* tem = root->left;
        root->left = root->right;
        root->right = tem;
        dfs(root->left);
        dfs(root->right);
        return root;
    }

    TreeNode* bfs(TreeNode* root){
        queue<TreeNode*> que;
        que.push(root);
        while (!que.empty()){
            TreeNode* curRoot = que.front();
            que.pop();
            if (!curRoot->left && !curRoot->right) continue;
            TreeNode* tem = curRoot->left;
            curRoot->left = curRoot->right;
            curRoot->right = tem;
            if (curRoot->left){
                que.push(curRoot->left);
            }
            if (curRoot->right){
                que.push(curRoot->right);
            }
        }
        return root;
    }

    TreeNode* invertTree(TreeNode* root) {
        if (!root) return root;
        // // 1 rec
        // return rec(root);
        // 2 dfs
        return dfs(root);
        // // 3 bfs
        // return bfs(root);
    }
};

234. 回文链表

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def isPalindrome(self, head: Optional[ListNode]) -> bool:
        fast, slow = head, head
        L = ListNode(-1).next
        while fast.next and fast.next.next:
            fast = fast.next.next
            tem = slow.next
            slow.next = L
            L = slow
            slow = tem
        if fast.next:
            if slow.val != slow.next.val:
                return False
            R = slow.next.next
        else:
            R = slow.next
        while L:
            if R.val != L.val:
                return False
            R, L = R.next, L.next
        return True
/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode* fast = head;
        ListNode* slow = head;
        ListNode* L =  nullptr;
        ListNode* R;
        while (fast->next && fast->next->next){
            fast = fast->next->next;
            ListNode* tem = slow->next;
            slow->next = L;
            L = slow;
            slow = tem;
        }
        if (fast->next){
            if (slow->val != slow->next->val){
                return false;
            }
            R = slow->next->next;
        }
        else{
            R = slow->next;
        }
        while (L){
            if (R->val != L->val){
                return false;
            }
            R = R->next;
            L = L->next;
        }
        return true;
    }
};

236. 二叉树的最近公共祖先

给定一个二叉树, 找到该树中两个指定节点的最近公共祖先。

百度百科中最近公共祖先的定义为:“对于有根树 T 的两个节点 p、q,最近公共祖先表示为一个节点 x,满足 x 是 p、q 的祖先且 x 的深度尽可能大(一个节点也可以是它自己的祖先)。”
# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root or root == p or root == q:
            return root
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        if not left:
            return right
        if not right:
            return left
        return root

238. 除自身以外数组的乘积

给你一个长度为 n 的整数数组 nums,其中 n > 1,返回输出数组 output ,其中 output[i] 等于 nums 中除 nums[i] 之外其余各元素的乘积。
class Solution:
    def productExceptSelf(self, nums: List[int]) -> List[int]:
        n = len(nums)
        table1 = [1] + [0] * (n) + [1]
        table2 = [1] + [0] * (n) + [1]
        res = [0] * (n)
        for i in range(1, n+1):
            table1[i] = table1[i-1] * nums[i-1]
        for j in range(n, 0, -1):
            table2[j] = table2[j+1] * nums[j-1]
        for i in range(n):
            res[i] = table1[i] * table2[i+2]
        return res

240. 搜索二维矩阵 II

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性:

每行的元素从左到右升序排列。
每列的元素从上到下升序排列。
class Solution:
    def searchMatrix(self, matrix: List[List[int]], target: int) -> bool:
        row, col = len(matrix), len(matrix[0])
        i, j = row-1, 0
        while i >= 0 and j < col:
            if matrix[i][j] == target:
                return True
            elif matrix[i][j] > target:
                i -= 1
            else:
                j += 1
        return False

279. 完全平方数

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

给你一个整数 n ,返回和为 n 的完全平方数的 最少数量 。

完全平方数 是一个整数,其值等于另一个整数的平方;换句话说,其值等于一个整数自乘的积。例如,14916 都是完全平方数,而 311 不是。
class Solution:
    def numSquares(self, n: int) -> int: 
        table = [x for x in range(n+1)]
        for i in range(2, n+1):
            j = 1
            while j*j <= i:
                table[i] = min(table[i], table[i-j*j]+1)
                j += 1
        return table[n]

283. 移动零

class Solution:
    def moveZeroes(self, nums: List[int]) -> None:
        """
        Do not return anything, modify nums in-place instead.
        """
        zeroIndex = 0
        for i in range(len(nums)):
            if nums[i] != 0:
                nums[zeroIndex], nums[i] = nums[i], nums[zeroIndex]
                zeroIndex += 1
class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int zeroIndex = 0;
        for (int i=0; i<nums.size(); i++){
            if (nums[i] != 0){
                swap(nums[i], nums[zeroIndex]);
                ++zeroIndex;
            }
        }
    }
};

287. 寻找重复数

给定一个包含 n + 1 个整数的数组 nums ,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。

假设 nums 只有 一个重复的整数 ,找出 这个重复的数 。

你设计的解决方案必须不修改数组 nums 且只用常量级 O(1) 的额外空间。

定义表格

class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        n = len(nums)
        table = [0] * n 
        for num in nums:
            if table[num] == 1:
                return num
            else:
                table[num] = 1

快慢指针


class Solution:
    def findDuplicate(self, nums: List[int]) -> int:
        slow, fast = 0, 0
        while True:
            fast = nums[nums[fast]]
            slow = nums[slow]
            if fast == slow:
                fast = 0
                while fast != slow:
                    fast = nums[fast]
                    slow = nums[slow]
                return fast

300. 最长递增子序列

给你一个整数数组 nums ,找到其中最长严格递增子序列的长度。

子序列是由数组派生而来的序列,删除(或不删除)数组中的元素而不改变其余元素的顺序。例如,[3,6,2,7] 是数组 [0,3,1,6,2,2,7] 的子序列。
class Solution:
    def lengthOfLIS(self, nums: List[int]) -> int:
        n = len(nums)
        table = [1] * n
        for i in range(1, n):
            for j in range(i):
                if nums[i] > nums[j]:
                    table[i] = max(table[i], table[j] + 1)
        return max(table)

309. 最佳买卖股票时机含冷冻期

给定一个整数数组,其中第 i 个元素代表了第 i 天的股票价格 。​

设计一个算法计算出最大利润。在满足以下约束条件下,你可以尽可能地完成更多的交易(多次买卖一支股票):

你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
卖出股票后,你无法在第二天买入股票 (即冷冻期为 1)。
示例:

输入: [1,2,3,0,2]
输出: 3 
解释: 对应的交易状态为: [买入, 卖出, 冷冻期, 买入, 卖出]
class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        # 当前天处理之后,f0代表拥有, f1代表冷冻期, f2没有拥有也没有处于冷冻期
        f0, f1, f2 = -prices[0], 0, 0
        for i in range(1, len(prices)):
            temf0 = max(f0, f2-prices[i])
            temf1 = f0 + prices[i]
            temf2 = max(f1, f2)
            f0, f1, f2 = temf0, temf1, temf2
        return max(f0, f1, f2)

322. 零钱兑换

给你一个整数数组 coins ,表示不同面额的硬币;以及一个整数 amount ,表示总金额。

计算并返回可以凑成总金额所需的 最少的硬币个数 。如果没有任何一种硬币组合能组成总金额,返回 -1 。

你可以认为每种硬币的数量是无限的。

示例 1:

输入:coins = [1, 2, 5], amount = 11
输出:3
解释:11 = 5 + 5 + 1

class Solution:
    def coinChange(self, coins: List[int], amount: int) -> int:
        table = [0] + [inf] * (amount)
        for i in range(amount+1):
            for coin in coins:
                if i-coin >= 0:
                    table[i] = min(table[i], table[i-coin] + 1)
        return table[amount] if table[amount] != inf else -1

337. 打家劫舍 III

在上次打劫完一条街道之后和一圈房屋后,小偷又发现了一个新的可行窃的地区。这个地区只有一个入口,我们称之为“根”。 除了“根”之外,每栋房子有且只有一个“父“房子与之相连。一番侦察之后,聪明的小偷意识到“这个地方的所有房屋的排列类似于一棵二叉树”。 如果两个直接相连的房子在同一天晚上被打劫,房屋将自动报警。

计算在不触动警报的情况下,小偷一晚能够盗取的最高金额。

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def rob(self, root: TreeNode) -> int:
        def backtrack(root):
            if not root:
                return 0,0
            yl, nl = backtrack(root.left)
            yr, nr = backtrack(root.right)
            return root.val+nl+nr, max(yl,nl)+max(yr,nr)
        return max(backtrack(root))

338. 比特位计数

class Solution:
    def contOne1(self, n):
        count = 0
        while n > 0:
            n = n & (n-1)
            count += 1
        return count
    def contOne2(self, n):
        out = [0]
        hightBit = 0
        for i in range(1, n+1):
            if (i & (i -1)) == 0:
                hightBit = i
            out.append(out[i-hightBit]+1)
        return out
    def contOne3(self, n):
        out = [0]
        for i in range(1, n+1):
            # out.append(out[i//2] + i % 2)
            out.append(out[i>>1] + (i & 1))
        return out
    def contOne4(self, n):
        out = [0]
        for i in range(1, n+1):
            out.append(out[i&(i-1)]+1)
        return out

    def countBits(self, n: int) -> List[int]:
        # # 1 Brian Kernighan 算法
        # return [self.contOne1(i) for i in range(n+1)]
        # # 2 动态规划-最高比特位
        # return self.contOne2(n)
        # # 3 动态规划-最低比特位
        # return self.contOne3(n)
        # 4 动态规划-最低设置位
        return self.contOne4(n)
class Solution {
public:
    vector<int> countOne1(int n){
        vector<int> out(n+1);
        for (int i=1; i<n+1; ++i){
            int count = 0;
            int tem = i;
            while (tem>0){
                tem = tem & (tem-1);
                ++count;
            }
            out[i] = count;
        }
        return out;
    }
    vector<int> countOne2(int n){
        vector<int> out(n+1);
        out[0] = 0;
        int higtBit = 0;
        for (int i=1; i<n+1; ++i){
            if ((i&(i-1))==0){
                higtBit = i;
            }
            out[i] = out[i-higtBit]+1;
        }
        return out;
    }
    vector<int> countOne3(int n){
        vector<int> out(n+1);
        out[0] = 0;
        for (int i=1; i<n+1; ++i){
            out[i] = out[i>>1] + (i&1);
        }
        return out;
    }
    vector<int> countOne4(int n){
        vector<int> out(n+1);
        out[0] = 0;
        for (int i=1; i<n+1; ++i){
            out[i] = out[(i&(i-1))] + 1;
        }
        return out;
    }
    vector<int> countBits(int n) {
        // // 1 Brian Kernighan 算法
        // return countOne1(n);
        // // 2 动态规划-最高有效位
        // return countOne2(n);
        // // 3 动态规划-最低有效位
        // return countOne3(n);
        // 4 动态规划-最低设置位
        return countOne4(n);
    }
};

347. 前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        nums = sorted(nums)
        res = [[nums[0],1]]
        n = len(nums)
        for i in range(1, n):
            if nums[i] == res[-1][0]:
                res[-1][1] += 1
            else:
                res.append([nums[i],1])
        res.sort(key=lambda x:x[1], reverse=True)
        out = []
        for i in range(k):
            out.append(res[i][0])
        return out

394. 字符串解码

给定一个经过编码的字符串,返回它解码后的字符串。

编码规则为: k[encoded_string],表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。

你可以认为输入字符串总是有效的;输入字符串中没有额外的空格,且输入的方括号总是符合格式要求的。

此外,你可以认为原始数据不包含数字,所有的数字只表示重复的次数 k ,例如不会出现像 3a 或 2[4] 的输入。

输入:s = "3[a]2[bc]"
输出:"aaabcbc"
class Solution:
    def decodeString(self, s: str) -> str:
        stack, res, multi = [[1,""]], "", 0
        for c in s:
            if "0" <= c <= "9":
                multi = multi*10 + int(c)
            elif c == '[':
                stack.append([multi, ""])
                multi = 0
            elif c == "]":
                curmutlti, curres = stack.pop()
                stack[-1][1] += curmutlti*curres
            else:
                stack[-1][1] += c
        return stack[0][1]

406. 根据身高重建队列

输入:people = [[7,0],[4,4],[7,1],[5,0],[6,1],[5,2]]
输出:[[5,0],[7,0],[5,2],[6,1],[4,4],[7,1]]
class Solution:
    def reconstructQueue(self, people: List[List[int]]) -> List[List[int]]:
        people.sort(key=lambda x:[-x[0], x[1]])
        res = []
        for per in people:
            res[per[1]:per[1]] = [per]
        return res

416. 分割等和子集

给你一个 只包含正整数 的 非空 数组 nums 。请你判断是否可以将这个数组分割成两个子集,使得两个子集的元素和相等。

 

示例 1:

输入:nums = [1,5,11,5]
输出:true
解释:数组可以分割成 [1, 5, 5][11]
class Solution:
    def canPartition(self, nums: List[int]) -> bool:
        n = len(nums)
        if n == 1:
            return False
        if sum(nums) % 2 == 1:
            return False
        target = sum(nums) // 2
        table = [True] + [False] * target
        for curnum in nums:
            for i in range(target, 0, -1):
                if i >= curnum:
                    table[i] = table[i-curnum] or table[i]
        return table[-1]

437. 路径总和 III

给定一个二叉树的根节点 root ,和一个整数 targetSum ,求该二叉树里节点值之和等于 targetSum 的 路径 的数目。

路径 不需要从根节点开始,也不需要在叶子节点结束,但是路径方向必须是向下的(只能从父节点到子节点)。

采用先序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pathSum(self, root: TreeNode, targetSum: int) -> int:
        res = [0]
        def backtrack(root, cursum, sumDic):
            if not root:
                return
            cursum += root.val
            if sumDic.get(cursum - targetSum, None):
                res[0] += sumDic.get(cursum - targetSum, None)
            sumDic[cursum] = sumDic.get(cursum, 0) + 1

            backtrack(root.left, cursum, sumDic)
            backtrack(root.right, cursum, sumDic)
            sumDic[cursum] -= 1

        backtrack(root, 0, {0:1})
        return res[0]

438. 找到字符串中所有字母异位词

给定两个字符串 s 和 p,找到 s 中所有 p 的 异位词 的子串,返回这些子串的起始索引。不考虑答案输出的顺序。

异位词 指字母相同,但排列不同的字符串。
class Solution:
    def findAnagrams(self, s: str, p: str) -> List[int]:
        tableS = [0] * 26
        tableP = [0] * 26
        for c in p:
            tableP[ord(c) - ord("a")] += 1
        lenp = len(p)
        lens = len(s)
        if lenp>lens:
            return []
        for i in range(lenp):
            tableS[ord(s[i]) - ord("a")] += 1
        if tableP == tableS:
            res = [0]
        else:
            res = []
        for j in range(1, lens-lenp+1):
            tableS[ord(s[j-1]) - ord("a")] -= 1
            tableS[ord(s[j+lenp-1]) - ord("a")] += 1
            if tableS == tableP:
                res.append(j)
        return res

448. 找到所有数组中消失的数字

class Solution:
    # def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
    #     out = []
    #     for i in range(len(nums)):
    #         index = nums[i] - 1
    #         while nums[i]!=0 and nums[index] != 0:
    #             tmpIndex = nums[index] - 1
    #             nums[index] = 0
    #             index = tmpIndex
    #     for i in range(len(nums)):
    #         if nums[i] != 0:
    #             out.append(i+1)
    #     return out

    def findDisappearedNumbers(self, nums: List[int]) -> List[int]:
        # out = []
        n = len(nums)
        for i in range(n):
            nums[(nums[i] - 1)%n] += n
        # for i in range(len(nums)):
        #     if nums[i] <= n:
        #         out.append(i+1)
        return [i+1 for i, num in enumerate(nums) if num<=n]
class Solution {
public:
    vector<int> findDisappearedNumbers(vector<int>& nums) {
        vector<int> out;
        int n=nums.size();
        for (int num:nums){
            int index = (num-1) % n;
            nums[index] += n;
        }
        for (int i=0; i<n; ++i){
            if (nums[i]<=n){
                out.push_back(i+1);
            }
        }
        return out;
    }
};

461. 汉明距离

class Solution:
    def countOne(self, n):
        if n == 1:
            return 1
        if n == 0:
            return 0
        return self.countOne(n&(n-1))+1
    def hammingDistance(self, x: int, y: int) -> int:
        return self.countOne(x^y)
class Solution {
public:
    int countOne(int n){
        if (0==n) return 0;
        if (1==n) return 1;
        return countOne(n&(n-1))+1;
    }
    int hammingDistance(int x, int y) {
        return countOne(x^y);
    }
};

494. 目标和

输入:nums = [1,1,1,1,1], target = 3
输出:5
解释:一共有 5 种方法让最终目标和为 3-1 + 1 + 1 + 1 + 1 = 3
+1 - 1 + 1 + 1 + 1 = 3
+1 + 1 - 1 + 1 + 1 = 3
+1 + 1 + 1 - 1 + 1 = 3
+1 + 1 + 1 + 1 - 1 = 3

# 递归
# class Solution:
#     def findTargetSumWays(self, nums: List[int], target: int) -> int:
#         allsum = sum(nums)
#         if (allsum + target) % 2 == 1:
#             return 0
#         tar = (allsum + target) // 2
#         res = [0]
#         def backtrack(choice, cursum):
#             if cursum == tar:
#                 res[0] += 1
#             if cursum > tar:
#                 return
#             for i in range(len(choice)):
#                 backtrack(choice[i+1:], cursum+choice[i])
#         nums.sort()
#         backtrack(nums, 0)
#         return res[0]

# 动态规划
class Solution:
    def findTargetSumWays(self, nums: List[int], target: int) -> int:
        allsum = sum(nums)
        if (allsum - target) % 2 == 1 or (allsum - target) < 0:
            return 0
        
        tar = (allsum - target) // 2
        table = [1] + [0] * tar
        for num in nums:
            for i in range(tar, -1, -1):
                if i>= num:
                    table[i] = table[i] + table[i-num]
        return table[-1]

543. 二叉树的直径

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def dfs(self, root, out):
        if root is None:
            return 0
        L = self.dfs(root.left, out)
        R = self.dfs(root.right, out)
        out[0] = max(out[0], L+R+1)
        return max(L,R)+1

    def diameterOfBinaryTree(self, root: Optional[TreeNode]) -> int:
        out = [0]
        self.dfs(root, out)
        return out[0]-1
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    int out;
    int dfs(TreeNode* root){
        if (!root) return 0;
        int L = dfs(root->left);
        int R = dfs(root->right);
        out = max(out, R+L+1);
        return max(L, R)+1;
    }
    int diameterOfBinaryTree(TreeNode* root) {
        dfs(root);
        return out-1;
    }
};

560. 和为K的子数组

输入:nums = [1,1,1], k = 2
输出: 2 , [1,1][1,1] 为两种不同的情况。
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        sumDic = {0:1}
        res = 0
        temSum = 0
        for num in nums:
            temSum += num
            if sumDic.get(temSum - k, "no") != "no":
                res += sumDic.get(temSum - k, "no")
            sumDic[temSum] = sumDic.get(temSum, 0) + 1
        return res

581. 最短无序连续子数组

输入:nums = [2,6,4,8,10,9,15]
输出:5
解释:你只需要对 [6, 4, 8, 10, 9] 进行升序排序,那么整个表都会变为升序排序。

class Solution:
    def findUnsortedSubarray(self, nums: List[int]) -> int:
        n = len(nums)
        left, right, leftmin, rightmax = 1, 0, inf, -inf

        for i in range(n):
            if nums[i] < rightmax:
                right = i
            else:
                rightmax = nums[i]

            if nums[n-i-1] > leftmin:
                left = n -i - 1
            else:
                leftmin = nums[n-i-1]
        return right-left+1

617. 合并二叉树

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def dfs(self, root1, root2):
        if root1 is None or root2 is None:
            return root1 if root1 else root2
        root1.left = self.dfs(root1.left, root2.left)
        root1.right = self.dfs(root1.right, root2.right)
        root1.val = root1.val + root2.val
        return root1
    def bfs(self, root1, root2):
        if root1 is None or root2 is None:
            return root1 if root1 else root2
        merged = TreeNode(root1.val + root2.val)
        que = [merged]
        que1 = [root1]
        que2 = [root2]
        while que1 and que2:
            node = que.pop()
            node1 = que1.pop()
            node2 = que2.pop()
            L1, R1 = node1.left, node1.right
            L2, R2 = node2.left, node2.right
            if L1 or L2:
                if L1 and L2:
                    left = TreeNode(L1.val + L2.val)
                    node.left = left
                    que.append(left)
                    que1.append(L1)
                    que2.append(L2)
                elif L1:
                    node.left = L1
                elif L2:
                    node.left = L2
            if R1 or R2:
                if R1 and R2:
                    right = TreeNode(R1.val + R2.val)
                    node.right = right
                    que.append(right)
                    que1.append(R1)
                    que2.append(R2)
                elif R1:
                    node.right = R1
                elif R2:
                    node.right = R2
        return merged
    def mergeTrees(self, root1: Optional[TreeNode], root2: Optional[TreeNode]) -> Optional[TreeNode]:
        # return self.dfs(root1, root2)
        return self.bfs(root1, root2)
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    TreeNode* dfs(TreeNode* root1, TreeNode* root2){
        if (!root1) return root2;
        if (!root2) return root1;
        root1->left = dfs(root1->left, root2->left);
        root1->right = dfs(root1->right, root2->right);
        root1->val = root1->val + root2->val;
        return root1;
    }
    TreeNode* bfs(TreeNode* t1, TreeNode* t2){
        if (!t1) return t2;
        if (!t2) return t1;
        TreeNode* merged = new TreeNode(t1->val + t2->val);
        queue<TreeNode*> que;
        queue<TreeNode*> que1;
        queue<TreeNode*> que2;
        que.push(merged);
        que1.push(t1);
        que2.push(t2);
        while (!que1.empty() && !que2.empty()){
            TreeNode* node = que.front(); 
            que.pop();
            TreeNode* node1 = que1.front();
            que1.pop();
            TreeNode* node2 = que2.front();
            que2.pop();
            TreeNode* L1 = node1->left;
            TreeNode* R1 = node1->right;
            TreeNode* L2 = node2->left;
            TreeNode* R2 = node2->right;
            if (L1 || L2){
                if (L1 && L2){
                    TreeNode* left = new TreeNode(L1->val + L2->val);
                    node->left = left;
                    que.push(left);
                    que1.push(L1);
                    que2.push(L2);
                }
                else if (L1){
                    node->left = L1;
                }
                else if (L2){
                    node->left = L2;
                }
            }
            if (R1 || R2){
                if (R1 && R2){
                    TreeNode* right = new TreeNode(R1->val + R2->val);
                    node->right = right;
                    que.push(right);
                    que1.push(R1);
                    que2.push(R2);
                }
                else if (R1){
                    node->right = R1;
                }
                else if (R2){
                    node->right = R2;
                }
            }
        }

        return merged;
    }
    TreeNode* mergeTrees(TreeNode* root1, TreeNode* root2) {
        // return dfs(root1, root2);
        return bfs(root1, root2);
    }
};

621. 任务调度器

输入:tasks = ["A","A","A","B","B","B"], n = 2
输出:8
解释:A -> B -> (待命) -> A -> B -> (待命) -> A -> B
     在本示例中,两个相同类型任务之间必须间隔长度为 n = 2 的冷却时间,而执行一个任务只需要一个单位时间,所以中间出现了(待命)状态。
class Solution:
    def leastInterval(self, tasks: List[str], n: int) -> int:
        table = [0] * 26
        for c in tasks:
            table[ord(c)-ord("A")] += 1
        maxc = max(table)
        total = (maxc-1) * (n+1)
        for i in table:
            if i == maxc:
                total += 1
        return max(total, len(tasks))

647. 回文子串

输入:"aaa"
输出:6
解释:6个回文子串: "a", "a", "a", "aa", "aa", "aaa"
class Solution:
    def countSubstrings(self, s: str) -> int:
        def countCurstring(left, right):
            cur = 0
            while left>=0 and right<len(s) and s[left] == s[right]:
                cur += 1
                left -= 1
                right += 1 
            return cur
        
        res = 0
        for i in range(len(s)):
            res += countCurstring(i, i)
            res += countCurstring(i, i+1)
        return res

739. 每日温度

请根据每日 气温 列表 temperatures ,请计算在每一天需要等几天才会有更高的温度。如果气温在这之后都不会升高,请在该位置用 0 来代替。

示例 1:

输入: temperatures = [73,74,75,71,69,72,76,73]
输出: [1,1,4,2,1,1,0,0]

class Solution:
    def dailyTemperatures(self, temperatures: List[int]) -> List[int]:
        stack = [0]
        res = [0] * len(temperatures)
        for i in range(1, len(temperatures)):
            while stack and temperatures[i] > temperatures[stack[-1]]:
                cur = stack.pop(-1)
                res[cur] = i - cur
            stack.append(i)
        return res

你可能感兴趣的:(算法,leetcode,python,c++)