python(c++)刷题+剑指offer

15. 二进制中1的个数

思路:一种是通过右移,一种是通过n&n-1不断减少1

python:

class Solution:
    def hammingWeight(self, n: int) -> int:
        res = 0
        while n:
            if n & 1:
                res += 1
            n >>= 1
        return res

c++实现:通过右移

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int res = 0;
        while(n){
            if(n & 1){
                res++;
            }
            n >>= 1;
        }
        return res;
    }
};

c++实现: 通过n&=n-1

class Solution {
public:
    int hammingWeight(uint32_t n) {
        int res = 0;
        while(n){
            res++;
            n &= n - 1;
        }
        return res;
    }
};

16. 数值的整数次方

思路:递归,注意分正负和奇数偶数即可

class Solution:
    def help(self, x, n):
        if x == 0:
            return 0
        if n == 0:
            return 1
        if n == 1:
            return x
        temp = self.help(x, n//2)
        if n % 2 == 1:
            return temp * temp * x
        else:
            return temp * temp
    def myPow(self, x: float, n: int) -> float:
        if n > 0:
            return self.help(x, n)
        else:
            return 1 / self.help(x, -n)

c++实现: 

class Solution {
public:
    double help(double x, long n){
        if(x == 0 || x == 1){
            return x;
        }
        if(n == 0){
            return 1;
        }
        if(n == 1){
            return x;
        }
        double temp = help(x, n/2);
        if(n % 2 == 1){
            return temp * temp * x;
        }
        else{
            return temp * temp;
        }
    }
    double myPow(double x, long n) {
        if(n > 0){
            return help(x, n);
        }
        else{
            return 1./help(x, -n);
        }
    }
};

17. 打印从1到最大的n位数

思路:如果没有考虑大数的话直接for循环就行

class Solution:
    def printNumbers(self, n: int) -> List[int]:
        self.res = []
        for m in range(1, 10**n):
            self.res.append(m)
        return self.res

考虑大数的做法,递归回溯,用字符串相加的方式就避免了数字超过范围

class Solution:
    def backtrace(self, count, track, length):
        if count == length:#终止条件 位数为length
            self.res.append(int(''.join(track)))
            return
        for i in range(10):
            store = track.copy()
            track.append(str(i))
            self.backtrace(count + 1, track, length)
            track = store
    def printNumbers(self, n: int) -> List[int]:
        self.res = []
        for m in range(1, n + 1):
            for start_num in range(1, 10):
                track = [str(start_num)]
                self.backtrace(1, track, m)
        return self.res

c++实现:

class Solution {
public:
    vector<int> res;
    void backtrace(int count, vector<char> track, int length){
        if(count == length){//长度相同 出去
            string temp_str = "";
            for (int i = 0; i < track.size(); i++){
                temp_str += track[i];
            }
            int int_str = atoi(temp_str.c_str());
            res.push_back(int_str);
			return ;
        }
        for(int i=0; i<10; i++){
            vector<char> store(track);
			track.push_back(i + '0');
            backtrace(count + 1, track, length);
            track = store;
        }
    }
    vector<int> printNumbers(int n) {       
        for(int m = 1; m < n+1; m++){
            for (int start_num = 1; start_num<10; start_num++){
                vector<char> track(1, start_num + '0');
                backtrace(1, track, m);
            }
        }
        return res;
    }
};

18. 删除链表的节点

思路:双指针

# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    def deleteNode(self, head: ListNode, val: int) -> ListNode:
        if head is None:
            return head
        new_head = ListNode(0)
        new_head.next = head
        pre = new_head
        cur = head
        while cur.val != val:
            pre = cur
            cur = cur.next
        pre.next = cur.next
        return new_head.next

c++实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if(head == NULL){
            return NULL;
        }
        ListNode* new_head = new ListNode(0);
        new_head->next = head;
        ListNode* pre = new_head;
        ListNode* cur = head;
        while(cur->val != val){
            pre = cur;
            cur = cur->next;
        }
        pre->next = cur->next;
        return new_head->next;
    }
};

c++递归:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteNode(ListNode* head, int val) {
        if(head == NULL){
            return NULL;
        }
        if(head->val == val){
            return head->next;
        }
        head->next = deleteNode(head->next, val);
        return head;
    }
};

19. 正则表达式匹配

思路:

class Solution:
    def matches(self, i, j, s, p):
            if i == 0:
                return False
            if p[j - 1] == '.':
                return True
            return s[i - 1] == p[j - 1]
    def isMatch(self, s: str, p: str) -> bool:
        m, n = len(s), len(p)
        dp = [[False] * (n + 1) for _ in range(m + 1)]
        dp[0][0] = True
        for i in range(m + 1):
            for j in range(1, n + 1):
                if p[j - 1] == '*':
                    dp[i][j] |= dp[i][j - 2]
                    if self.matches(i, j - 1, s, p):
                        dp[i][j] |= dp[i - 1][j]
                else:
                    if self.matches(i, j, s, p):
                        dp[i][j] |= dp[i - 1][j - 1]
        return dp[-1][-1]

c++:

class Solution {
public:
    bool help(int i, int j, string s, string p){
        if(i == 0){
            return false;
        }
        if(p[j-1] == '.'){
            return true;
        }
        return s[i-1] == p[j-1];
    }
    bool isMatch(string s, string p) {
        int m = s.size();
        int n = p.size();
        vector<vector<int>> dp(m + 1, vector<int>(n + 1, 0));
        dp[0][0] = 1;
        for(int i = 0; i < m + 1; i++){
            for (int j = 1; j < n + 1; j++){
                if(p[j-1] == '*'){
                    dp[i][j] |= dp[i][j-2];
                    if(help(i, j-1, s, p)){
                        dp[i][j] |= dp[i-1][j];
                    }
                }
                else{
                    if (help(i, j, s, p)){
                        dp[i][j] |= dp[i-1][j-1];
                    }
                }
            }
        }
        return dp[m][n];
    }
};

20. 表示数值的字符串

python:

class Solution:
    def isNumber(self, s: str) -> bool:
        try:
            float(s)
        except Exception as e:
            print('==error:',e)
            return False
        return True

c++实现:

class Solution {
public:
    bool isNumber(string s) {
        if(s.empty()) return false;
        while(s.length() > 0 && s[0] == ' ') s.erase(0, 1);
        while(s.length() > 0 && s[s.length() - 1] == ' ') s.erase(s.length() - 1, 1);
        if(s.length() == 0) return false;
        bool isDot = false, isE = false, isNumber = false;
        for(int i=0; i<s.length(); ++i)
        {
            if(s[i] >= '0' && s[i] <= '9') 
                isNumber = true;
            else if(s[i] == 'e' || s[i] == 'E')
            {
                if(isE || !isNumber || i == s.length() - 1) return false;
                s[i] = 'e'; // 将'E'变成'e'
                isE = true;
            }
            else if(s[i] == '+' || s[i] == '-')
            {
                if((i > 0 && s[i - 1] != 'e') || (i == s.length() - 1)) return false;
            }
            else if(s[i] == '.')
            {
                if(isDot || isE || (i == s.length() - 1 && !isNumber)) return false;
                isDot = true;
            }
            else return false;
        }
        return true;
    }
};

21. 调整数组顺序使奇数位于偶数前面

思路:双指针 奇数放左边  偶数放右边

class Solution:
    def exchange(self, nums: List[int]) -> List[int]:
        left = 0
        right = len(nums) - 1
        while left<right:
            if nums[left]%2:#奇数左指针就一直右移
                left += 1
                continue
            if nums[right]%2 == 0:#偶数右指针就一直左移
                right -= 1
                continue
            nums[left], nums[right] = nums[right],nums[left]
        return nums

c++实现:

class Solution {
public:
    void swap(int &a, int &b){
        int temp = a;
        a = b;
        b = temp;
    }
    vector<int> exchange(vector<int>& nums) {
        int left = 0, right = nums.size() - 1;
        while(left < right){
            if(nums[left] % 2){
                left++;
                continue;
            }
            if(nums[right] % 2 == 0){
                right--;
                continue;
            }
            swap(nums[left], nums[right]);       
        }
        return nums;
    }
};

22. 链表中倒数第k个节点

思路:双指针

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

class Solution:
    def getKthFromEnd(self, head: ListNode, k: int) -> ListNode:
        node_A = head
        node_B = head
        while k:
            node_A = node_A.next
            k -= 1
        while node_A:
            node_A = node_A.next
            node_B = node_B.next
        return node_B

c++实现: 

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        ListNode* node_A = head;
        ListNode* node_B = head;
        while(k>0){
            node_A = node_A->next;
            k--;
        }
        while(node_A != NULL){
            node_A = node_A->next;
            node_B = node_B->next;
        }
        return node_B;
        
    }
};

24. 反转链表

python代码:

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

class Solution:
    def reverseList(self, head: ListNode) -> ListNode:
        pre = None
        cur = head
        while cur:
            temp = cur.next
            cur.next = pre
            pre = cur
            cur = temp
        return pre

c++实现:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* pre = NULL;
        ListNode* cur = head;
        while(cur){
            ListNode* temp = cur->next;
            cur->next = pre;
            pre = cur;
            cur = temp;
        }
        return pre;
    }
};

25. 合并两个排序的链表

python:

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

class Solution:
    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        fake_head_node  = ListNode(0)

        cur = fake_head_node

        while l1 and l2:
            if l1.val<l2.val:
                cur.next = l1
                l1 = l1.next
            else:
                cur.next = l2
                l2 = l2.next            
            cur = cur.next
        
        if l1:
            cur.next = l1
        else:
            cur.next = l2

        return fake_head_node.next

c++:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        ListNode* new_head = new ListNode(0);
        ListNode* node = new_head;

        while(l1!=NULL && l2 !=NULL){
            if(l1->val<l2->val){
                node->next = l1;
                l1 = l1->next;
            }
            else{
                node->next  = l2;
                l2 = l2->next;                
            }
            node = node->next;
        }

        if (l1!=NULL){
            node->next = l1;
        }
        if(l2!=NULL){
            node->next = l2;
        }
        return new_head->next;
    }
};

26. 树的子结构

思路:

B为空 说明B已经遍历完成

A为空或者A, B两个节点的值不相等则返回false

对A和B节点进行递归调用  对A的左右子节点分别进行递归调用  可能A的子结构等于B的在深处

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def help(self, A, B):
        if B is None:#B为空 说明B已经遍历完成
            return True
        if (A is None) or (A.val != B.val):#A为空或者A, B两个节点的值不相等则返回false
            return False
        return self.help(A.left, B.left) and self.help(A.right, B.right)

    def isSubStructure(self, A: TreeNode, B: TreeNode) -> bool:
        if A is None or B is None:
            return False
        #对A和B节点进行递归调用  对A的左右子节点分别进行递归调用  可能A的子结构在深处
        return self.help(A, B) or self.isSubStructure(A.left, B) or self.isSubStructure(A.right, B)

c++实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool help(TreeNode* A, TreeNode* B){
        if(B == NULL){
            return true;
        }
        if((A == NULL) || (A->val != B->val)){
            return false;
        }
        return help(A->left, B->left) && help(A->right, B->right);
    }
    bool isSubStructure(TreeNode* A, TreeNode* B) {
        if(A == NULL || B == NULL){
            return false;
        }
        return help(A, B) || isSubStructure(A->left, B) || isSubStructure(A->right, B);
    }
};

27. 二叉树的镜像

思路;其实就是翻转二叉树,分别对左右子树进行交换,递归即可,出口是节点为none

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def mirrorTree(self, root: TreeNode) -> TreeNode:   
        if root is None:
            return None
        left = self.mirrorTree(root.left)
        right = self.mirrorTree(root.right)
        root.right = left
        root.left = right
        return root

c++实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* mirrorTree(TreeNode* root) {
        if(root == NULL){
            return root;
        }
        TreeNode* left =  mirrorTree(root->left);
        TreeNode* right =  mirrorTree(root->right);
        root->left = right;
        root->right = left;
        return root;
    }
};

28. 对称的二叉树

思路:递归判断左右子树是否相等,找准递归出口就行

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def help(self, node1, node2):
        if node1 == None and node2 == None:
            return True
        if node1 == None or node2 == None:
            return False
        if node1.val != node2.val:
            return False
        return self.help(node1.left, node2.right) and self.help(node1.right, node2.left)
    def isSymmetric(self, root: TreeNode) -> bool:
        return self.help(root, root)

c++实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    bool help(TreeNode* node1, TreeNode* node2){
        if(node1 == NULL && node2 == NULL){
            return true;
        }
        if(node1 == NULL || node2 == NULL){
            return false;
        }
        if(node1->val != node2->val){
            return false;
        }
        return help(node1->left, node2->right) && help(node1->right, node2->left);
    }
    bool isSymmetric(TreeNode* root) {
        return help(root, root);
    }
};

29. 顺时针打印矩阵

思路:从外层到内层循环,终止条件就是左上角索引和右上角索引重合时

class Solution:
    def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
        h = len(matrix)
        if h == 0:
            return []
        w = len(matrix[0])
        left = 0
        right = w - 1
        top = 0
        bottom = h - 1
        res = []
        while left<=right and top<=bottom:
            for i in range(left, right + 1):
                res.append(matrix[top][i])
            for i in range(top + 1, bottom + 1):
                res.append(matrix[i][right])
            if left < right and top < bottom:
                for i in range(right-1, left-1, -1):
                    res.append(matrix[bottom][i])
                for i in range(bottom-1, top, -1):
                    res.append(matrix[i][left])
            left+=1
            right-=1
            top+=1
            bottom-=1
            # print('==res:',res)
        return res

c++实现:

class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> res;
        int h = matrix.size();
        if(h<1){
            return res;
        }
        int w = matrix[0].size();
        int left = 0, top = 0, right = w - 1, bottom = h - 1;
        while (left <= right && top <= bottom){
            for (int i = left; i < right+1; i++){
                res.push_back(matrix[top][i]);
            }
            for (int i = top + 1; i < bottom + 1; i++){
                res.push_back(matrix[i][right]);
            }
            if(left<right && top<bottom){
                for (int i = right - 1; i > left-1; i--){
                    res.push_back(matrix[bottom][i]);
                }
                for (int i = bottom - 1; i > top; i--){
                    res.push_back(matrix[i][left]);
                }
            }
            left++;
            right--;
            top++;
            bottom--;
            // cout<<"res:"<<res<<endl;
        }
        return res;

    }
};

30. 包含min函数的栈

python:

class MinStack:

    def __init__(self):
        """
        initialize your data structure here.
        """
        self.stack = []


    def push(self, x: int) -> None:
        self.stack.append(x)

    def pop(self) -> None:
        self.stack.pop()

    def top(self) -> int:
        return self.stack[-1]

    def min(self) -> int:
        return min(self.stack)



# Your MinStack object will be instantiated and called as such:
# obj = MinStack()
# obj.push(x)
# obj.pop()
# param_3 = obj.top()
# param_4 = obj.min()

c++:

class MinStack {
public:
    stack<int> stack_A;
    stack<int> min_stack;
    /** initialize your data structure here. */
    MinStack() {

    }
    
    void push(int x) {
        stack_A.push(x);
        if(min_stack.empty() || min_stack.top()>=x){
            min_stack.push(x);
        }
    }
    
    void pop() {
        if(stack_A.top() == min_stack.top()){
            min_stack.pop();
        }
        stack_A.pop();
    }
    
    int top() {
        return stack_A.top();
    }
    
    int min() {
        return min_stack.top();
    }
};

/**
 * Your MinStack object will be instantiated and called as such:
 * MinStack* obj = new MinStack();
 * obj->push(x);
 * obj->pop();
 * int param_3 = obj->top();
 * int param_4 = obj->min();
 */

31. 栈的压入、弹出序列

思路:用栈 遇到相等的 就一直出栈

class Solution:
    def validateStackSequences(self, pushed: List[int], popped: List[int]) -> bool:
        stack = []
        index = 0
        for i in range(len(pushed)):
            stack.append(pushed[i])
            while stack and stack[-1]==popped[index]:
                stack.pop()
                index += 1
        return not stack

c++实现:

class Solution {
public:
    bool validateStackSequences(vector<int>& pushed, vector<int>& popped) {
        stack<int> stack_A;
        int index = 0;
        for(int i=0; i<pushed.size(); i++){
            stack_A.push(pushed[i]);
            while(!stack_A.empty() && stack_A.top() == popped[index]){
                index++;
                stack_A.pop();
            }
        }
        return stack_A.empty();
    }
};

32 - I. 从上到下打印二叉树

思路:bfs

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[int]:
        res = []
        if root is None:
            return res
        queue = [root]
        while queue:
            for i in range(len(queue)):
                node = queue.pop(0)
                res.append(node.val)
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
        return res

c++实现: 

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> levelOrder(TreeNode* root) {
        vector<int> res;
        if(root == NULL){
            return res;
        }
        queue<TreeNode*> queue_A;
        queue_A.push(root);
        while(!queue_A.empty()){
            int count = queue_A.size();
            for(int i=0; i<count; i++){
                TreeNode* node = queue_A.front();
                res.push_back(node->val);
                queue_A.pop();
                if(node->left){
                    queue_A.push(node->left);
                }
                if(node->right){
                    queue_A.push(node->right);
                }
            }
        }
        return res;
    }
};

32 - II. 从上到下打印二叉树 II

思路:bfs 迭代

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res = []
        if not root:
            return res
        quene= [root]
        while quene:            
            temp = []
            for i in range(len(quene)):
                node = quene.pop(0)
                temp.append(node.val)                
                if node.left:
                    quene.append(node.left)
                if node.right:          
                    quene.append(node.right)
            res.append(temp)        
        return res

c++实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        if(root == NULL){
            return res;
        }
        queue<TreeNode* > queue_A;
        queue_A.push(root);
        while(!queue_A.empty()){
            vector <int> temp;
            int count = queue_A.size();            
            for(int i=0; i<count; i++){
                TreeNode* node = queue_A.front();
                temp.push_back(node->val);
                queue_A.pop();
                if(node->left){
                    queue_A.push(node->left);
                }
                if(node->right){
                    queue_A.push(node->right);
                }
            }
            res.push_back(temp);
        }
        return res;
    }
};

32 - III. 从上到下打印二叉树 III

思路:利用队列 bfs 层次遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        res = []
        if root is None:
            return res
        quene = [root]
        while quene:
            temp = []
            for i in range(len(quene)):
                node = quene.pop(0)
                temp.append(node.val)
                if node.left:
                    quene.append(node.left)
                if node.right:
                    quene.append(node.right)
            if len(res)%2==0:
                res.append(temp)
            else:
                res.append(temp[::-1])
        return res

c++实现:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<vector<int>> levelOrder(TreeNode* root) {
        vector<vector<int>> res;
        if(root == NULL){
            return res;
        }
        queue<TreeNode*> queue_A;
        queue_A.push(root);
        while(!queue_A.empty()){
            vector<int> temp;
            int count = queue_A.size();
            for(int i=0; i<count; i++){
                TreeNode* node =  queue_A.front();
                temp.push_back(node->val);
                queue_A.pop();
                if(node->left){
                    queue_A.push(node->left);
                }
                if(node->right){
                    queue_A.push(node->right);
                }
            }
            if(res.size() % 2 == 0){
                res.push_back(temp);
            }
            else{
                reverse(temp.begin(), temp.end());
                res.push_back(temp);
            }
        }
        return res;
    }
};

33. 二叉搜索树的后序遍历序列

思路:递归根据 后序遍历 左右根和二叉搜索树特点

class Solution:
    def help(self, left, right, postorder):
        if left>=right:
            return True
        m = left
        while postorder[m]<postorder[right]:
            m += 1 #找到根节点
        p = m
        while postorder[p]>postorder[right]:
            p += 1 #找到大于根节点的值的索引
        return p == right and self.help(left, m - 1, postorder) and self.help(m, right-1, postorder)
    def verifyPostorder(self, postorder: List[int]) -> bool:

        return self.help(0, len(postorder) - 1, postorder)

c++实现:

class Solution {
public:
    bool help(int left, int right, vector<int>& postorder){
        if(left>=right){
            return true;
        }
        int m = left;
        while(postorder[m]<postorder[right]){
            m++;
        }
        int p = m;
        while(postorder[p]>postorder[right]){
            p++;
        }
        return (p == right) && help(left, m-1, postorder) && help(m, right-1, postorder);
    }
    bool verifyPostorder(vector<int>& postorder) {
        return help(0, postorder.size() - 1, postorder);
    }
};

35. 复杂链表的复制

思路:其实就是深拷贝 ,这里采用dfs。

从头结点 head 开始拷贝;
由于一个结点可能被多个指针指到,因此如果该结点已被拷贝,则不需要重复拷贝;
如果还没拷贝该结点,则创建一个新的结点进行拷贝,并将拷贝过的结点保存在哈希表中;
使用递归拷贝所有的 next 结点,再递归拷贝所有的 random 结点。

python:

"""
# Definition for a Node.
class Node:
    def __init__(self, x: int, next: 'Node' = None, random: 'Node' = None):
        self.val = int(x)
        self.next = next
        self.random = random
"""
#其实就是考验深拷贝
class Solution:
    def help(self, node, view):#dfs
        if node is None:
            return node
        if node in view:#已经出现过
            return view[node]
        new_node = Node(node.val, None, None)
        view[node] = new_node
        new_node.next = self.help(node.next, view)
        new_node.random = self.help(node.random, view)
        return new_node
    def copyRandomList(self, head: 'Node') -> 'Node':
        view = {}
        return self.help(head, view)


c++:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* next;
    Node* random;
    
    Node(int _val) {
        val = _val;
        next = NULL;
        random = NULL;
    }
};
*/
class Solution {
public:
    map<Node*, Node*> view;
    Node* help(Node* node){
        if(node == nullptr){
            return nullptr;
        }
        if(view.count(node)){//已经出现过了的节点 返回就行
            return view[node];
        }
        Node* new_node = new Node(node->val);
        view[node] = new_node;//记录已经创建的节点
        new_node->next = help(node->next); 
        new_node->random = help(node->random); 
        return new_node;
    }
    Node* copyRandomList(Node* head) {
        
        return help(head);
    }
};

36. 二叉搜索树与双向链表

思路:中序遍历 设定一个前驱节点pre用来形成双向链接

"""
# Definition for a Node.
class Node:
    def __init__(self, val, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
"""
class Solution:
    def help(self, node):#中序遍历
        if node is not None:
            self.help(node.left)#递归左子树
            if self.pre is not None:
                self.pre.right, node.left = node, self.pre #pre和node节点形成双向节点形式
            else:
                self.head = node #第一次出现 记录head节点
            self.pre = node #保存pre节点 并一直不停更新
            self.help(node.right)#递归右子树
    def treeToDoublyList(self, root: 'Node') -> 'Node':
        if root is None:
            return 
        self.pre = None
        self.head = None
        self.help(root)
        self.head.left, self.pre.right = self.pre, self.head
        return self.head

c++实现:

/*
// Definition for a Node.
class Node {
public:
    int val;
    Node* left;
    Node* right;

    Node() {}

    Node(int _val) {
        val = _val;
        left = NULL;
        right = NULL;
    }

    Node(int _val, Node* _left, Node* _right) {
        val = _val;
        left = _left;
        right = _right;
    }
};
*/
class Solution {
public:
    Node* pre;
    Node* head;
    void help(Node* node) {
        if(node==NULL){
            return;
        }
        help(node->left);
        if(pre != NULL) {
            pre->right = node;
            node->left = pre;
        }
        else{
            head = node;
        }
        pre = node;
        help(node->right);
    }
    Node* treeToDoublyList(Node* root) {
        if(root == NULL){
            return NULL;
        }
        help(root);
        head->left = pre;
        pre->right = head;
        return head;

    }
};

38. 字符串的排列

思路:回溯  注意有重复字符串 要剪枝  这里用 view记录 出现过的

python

class Solution:
    def backtrace(self, s, view, track):
        if len(track) == len(s):
            self.res.append(track)
            return
        for i in range(len(s)):
            if view[i]:
                continue
            if i>0 and s[i]==s[i-1] and view[i-1]==0:
                continue
            view[i] = 1
            store = track
            track += s[i]
            self.backtrace(s, view, track)
            track = store
            view[i] = 0
    def permutation(self, s: str) -> List[str]:
        self.res = []
        s = sorted(s)
        self.backtrace(s, [0]*len(s), '')
        return self.res

c++实现:

class Solution {
public:
    vector<string> res;
    void backtrace(string s, vector<int> view, string track){
        if(s.size() == track.size()){
            res.push_back(track);
            return;
        }
        for(int i=0; i<s.size(); i++){
            if(view[i]){
                continue;
            }
            if(i>0 && s[i] == s[i-1] && view[i-1] == 0){
                continue;
            }
            view[i] = 1;
            string store = track;
            track += s[i];
            backtrace(s, view, track);
            track = store;
            view[i] = 0;
        }
        return;
    }
    vector<string> permutation(string s) {
        vector<int> view(s.size(), 0);
        sort(s.begin(), s.end());
        backtrace(s, view, "");
        return res;
    }
};

39. 数组中出现次数超过一半的数字

python代码:

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        return sorted(nums)[len(nums)//2]

c++代码:

class Solution {
public:
    int majorityElement(vector<int>& nums) {
        int length = nums.size();
        sort(nums.begin(), nums.end());
        return nums[length/2];
    }
};

投票法(最优解):

class Solution:
    def majorityElement(self, nums: List[int]) -> int:
        votes = 0
        for num in nums:
            if votes == 0:
                x = num
            if num == x:
                votes += 1
            else:
                votes -= 1
            # print('==x:', x)
            # print('==votes:', votes)
        return x

40. 最小的k个数

python:

class Solution:
    def quicksort(self, arr):
        if len(arr) <= 1:
            return arr
        privit = arr[len(arr)//2]
        middle = [x for x in arr if x == privit]
        left = [x for x in arr if x < privit]
        right = [x for x in arr if x > privit]
        return self.quicksort(left) + middle + self.quicksort(right)
    def getLeastNumbers(self, arr: List[int], k: int) -> List[int]:
        return self.quicksort(arr)[:k]

c++实现快排:

class Solution {
public:
    vector<int> quickSort(vector<int>& arr){
        if(arr.size() <= 1){
            return arr;
        }
        int length = arr.size();
        int privit = arr[length/2];
        vector<int> left;
        vector<int> right;
        vector<int> middle;
        for(int i=0; i<length; i++){
            if(privit == arr[i]){
                middle.push_back(arr[i]);
            }
            else if(privit > arr[i]){
                left.push_back(arr[i]);
            }
            else{
                right.push_back(arr[i]);
            }
        }
        vector<int> left_sort = quickSort(left);
        vector<int> middle_sort = middle;
        vector<int> right_sort = quickSort(right);

        left_sort.insert(left_sort.end(), middle_sort.begin(), middle_sort.end());
        left_sort.insert(left_sort.end(), right_sort.begin(), right_sort.end());
        return left_sort;
    }
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        vector<int> sort_arr = quickSort(arr);
        vector<int> res;
        for(int i=0; i<k; i++){
            res.push_back(sort_arr[i]);
        }
        return res;

    }
};

c++调用现成的排序:

class Solution {
public:
    vector<int> getLeastNumbers(vector<int>& arr, int k) {
        sort(arr.begin(), arr.end());
        vector<int> res;
        for(int i=0; i<k; i++){
            res.push_back(arr[i]);
        }
        return res;

    }
};

42. 连续子数组的最大和

思路:动态规划

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        dp = [0]*len(nums)
        dp[0] = nums[0]
        for i in range(1, len(nums)):
            dp[i] = max(nums[i], dp[i-1]+nums[i])
        # print(dp)
        return max(dp)

思路:修改数组:

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums)==0:
            return []
        res = nums[0]
        for i in range(1,len(nums)):
            nums[i] = max(nums[i], nums[i] + nums[i-1])
            res = max(nums[i], res)
        return res

思路:修改数组2 

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        for i in range(1,len(nums)):
            nums[i]+=max(nums[i-1],0)
        return max(nums)

思路:借助一个变量

o(1),0(n)

class Solution:
    def maxSubArray(self, nums: List[int]) -> int:
        if len(nums)==0:
            return []
        value = nums[0]
        res = nums[0]
        for i in range(1,len(nums)):
            value = max(nums[i], value + nums[i])
            res = max(value, res)
        return res

c++实现

class Solution {
public:
    int maxSubArray(vector<int>& nums) {
        int length = nums.size();
        vector<int> dp(length, 0);
        dp[0] = nums[0];
        for (int i=1; i<length; i++){
            dp[i] = max(nums[i], nums[i] + dp[i-1]);
        }
        int maxValue = *max_element(dp.begin(), dp.end());
        return maxValue;
    }
};

44. 数字序列中某一位的数字

思路:

python代码:

class Solution:
    def findNthDigit(self, n: int) -> int:
        base = 9
        digit_nums = 1
        while n - base * digit_nums > 0:
            n -= base * digit_nums
            base *= 10
            digit_nums += 1
        # print('==n:', n)
        # 计算target的值
        idx = n % digit_nums  # 注意由于上面的计算,n现在表示digits位数的第n个数字
        # print('==idx:', idx)
        if idx == 0:
            idx = digit_nums
        number = 1
        for i in range(1, digit_nums):
            number *= 10
        # print('==digit_nums:', digit_nums)
        if idx == digit_nums:
            number += n // digit_nums - 1
        else:
            number += n // digit_nums
        # print('==number:', number)
        return int(str(number)[idx-1])

c++代码:

class Solution {
public:
    int findNthDigit(int n) {
        long base = 9;
        int digit_nums = 1;
        while(n - base * digit_nums > 0){
            n -= base*digit_nums;
            base *=10;
            digit_nums++;
        }
        int index = n % digit_nums;
        if(index == 0){
            index = digit_nums;
        }
        long number = 1;
        for(int i=1;i<digit_nums;i++){
            number *= 10;
        }
        if(index == digit_nums){
            number += n/digit_nums -1;
        }
        else{
            number += n/digit_nums;
        }
        return int(to_string(number)[index - 1])-'0';
    }
};

45. 把数组排成最小的数

思路:其实就是排序 这里采用快排  将合并后偏小的字母移动到左边  等于的移动到中间 大于的移动到右边

class Solution:
    def minNumber(self, nums: List[int]) -> str:
        def fast_sort(arr):
            if len(arr) <= 1:
                return arr
            privot = arr[len(arr)//2]
            left = [x for x in arr if x + privot < privot + x]
            middle = [x for x in arr if x == privot or x + privot == privot + x]
            right = [x for x in arr if x + privot > privot + x]
            # print('===left===:', left)
            # print('===right===:', right)
            # print('====middle:', middle)
            return fast_sort(left) + middle + fast_sort(right)
        strs = [str(num) for num in nums]
        # fast_sort(0, len(strs) - 1)
        new_strs = fast_sort(strs)
        # print('==new_strs:', new_strs)
        return ''.join(new_strs)

c++实现:

class Solution {
public:
    vector<string> quickSort(vector<string> strs) {
        if(strs.size() <= 1){
            return strs;
        }
        vector<string> left;
        vector<string> middle;
        vector<string> right;
        string privit = strs[int(strs.size()/2)];
        for(int i=0; i<strs.size(); i++){
            if (strs[i] + privit < privit + strs[i]){
                left.push_back(strs[i]);
            }            
        }
        for(int i=0; i<strs.size(); i++){
            if ((strs[i] == privit) || (strs[i] + privit == privit + strs[i])){
                middle.push_back(strs[i]);
            }            
        }
        for(int i = 0; i<strs.size(); i++){
            if (strs[i] + privit > privit + strs[i]){
                right.push_back(strs[i]);
            }            
        }
        vector<string> left_sort = quickSort(left);
        vector<string> middle_sort = middle;
        vector<string> right_sort = quickSort(right);
        left_sort.insert(left_sort.end(), middle_sort.begin(), middle_sort.end());
        left_sort.insert(left_sort.end(), right_sort.begin(), right_sort.end());
        return left_sort;
    }
    string minNumber(vector<int>& nums) {
        vector<string> strs;
        for(int i=0; i<nums.size(); i++){
            strs.push_back(to_string(nums[i]));
        }
        vector<string> new_strs= quickSort(strs);
        string res;
        for(int i=0;i<new_strs.size();i++){
            res += new_strs[i];
        }
        return res;
    }
};

46. 把数字翻译成字符串

思路:动态规划,dp[i] = dp[i-1]+dp[i-2] 满足1~25之间

class Solution:
    def translateNum(self, num):
        if 0<=num<=9:return 1
        nums = [i for i in str(num)]
        print(nums)
        n = len(nums)
        dp = [0]*n
        dp[0] = 1
        if nums[0] == '1' or (nums[0] == '2' and nums[1] <= '5'):
            dp[1] = 2
        else:
            dp[1] = 1
        for i in range(2, n):
            if nums[i-1] == '1' or (nums[i-1] == '2' and nums[i] <= '5'):
                dp[i] = dp[i-1]+dp[i-2]
            else:
                dp[i] = dp[i-1]
        print(dp)
        return dp[-1]
num = 12258
sol = Solution()
sol.translateNum(num)

压缩一下空间,复杂度变为o(n) 

class Solution:
    def translateNum(self, num):
        if 0<=num<=9:return 1
        nums = [i for i in str(num)]
        print(nums)
        n = len(nums)
        dp_zero = 1
        if nums[0]=='1' or (nums[0]=='2' and nums[1] <= '5'):
            dp_one = 2
        else:
            dp_one = 1

        for i in range(2, n):
            temp = dp_zero
            dp_zero = dp_one
            if nums[i-1] == '1' or (nums[i-1] == '2' and nums[i] <= '5'):
                dp_one = temp+dp_zero
        print(dp_one)
        return dp_one
num = 12258
sol = Solution()
sol.translateNum(num)

c++实现:

class Solution {
public:
    int translateNum(int num) {
        if(0<=num && num<=9){
            return 1;
        }
        string num_string = to_string(num);        
        int length = num_string.size();
        vector<int> dp(length, 0);
        dp[0] = 1;
        if(num_string[0] == '1' || (num_string[0] == '2' && num_string[1] <= '5')){
            dp[1] = 2;
        }
        else{
            dp[1] = 1;
        }
        for (int i=2; i<length; i++){
            if(num_string[i-1] == '1' || (num_string[i-1] == '2' && num_string[i] <= '5')){
                dp[i] = dp[i-1] + dp[i-2];
            // cout<<"==hahahahahaha=="<<endl;
        }
            else{
                dp[i] = dp[i-1];
            }
        }
        return dp[length-1];
    }
};

47. 礼物的最大价值

思路:动态规划:

python代码:

class Solution:
    def maxValue(self, grid: List[List[int]]) -> int:
        h = len(grid)
        w = len(grid[0])
        dp = [[0 for _ in range(w)] for _ in range(h)]
        # print(np.array(dp))
        dp[0][0] = grid[0][0]
        for i in range(1, h):
            dp[i][0] = dp[i-1][0]+grid[i][0]
        # print(np.array(dp))
        for i in range(1, w):
            dp[0][i] = dp[0][i-1]+grid[0][i]
        # print(np.array(dp))
        for i in range(1,h):
            for j in range(1,w):
                dp[i][j] = max(dp[i-1][j],dp[i][j-1])+grid[i][j]
        # print(np.array(dp))
        return dp[-1][-1]

c++实现:

class Solution {
public:
    int maxValue(vector<vector<int>>& grid) {
        int h = grid.size();
        int w = grid[0].size();

        vector<vector<int>> dp(h, vector<int>(w));
        dp[0][0] = grid[0][0];
        
        for (int i=1;i<h;i++){
            dp[i][0]=dp[i-1][0]+grid[i][0];
        }
        for (int i=1;i<w;i++){
            dp[0][i]=dp[0][i-1]+grid[0][i];
        }
        for(int i=1;i<h;i++){
            for(int j=1;j<w;j++){
                dp[i][j]= max(dp[i-1][j],dp[i][j-1])+grid[i][j];
            } 
        }
        return dp[h-1][w-1];
    }
};

48. 最长不含重复字符的子字符串

思路:滑动窗口

python代码:

class Solution:
    def lengthOfLongestSubstring(self, s: str) -> int:
        left,right =0,0
        dict_ = {}
        res = 0
        while right<len(s):
            dict_[s[right]] = dict_.get(s[right], 0) + 1
            while dict_[s[right]]>1:
                dict_[s[left]]-=1
                left+=1
            res = max(res, right - left + 1)
            right+=1
        # print(res)
        return res

c++实现:

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int left=0;
        int right = 0;
        int res=0;
        map<int,int>dict_;
        while(right<s.size()){
            dict_[s[right]]++;
            while(dict_[s[right]]>1){
                dict_[s[left]]--;              
                left++;
            }
            res = max(res, right-left+1);
            right+=1;
        }
        return res;

    }
};

49.丑数

思路:题目要求的这个数字一定是由单个或者多个2,3,5的乘积,如果从小到大去枚举在判断是否由2,3,5乘积组成,工作量会很大,所以考虑用2,3,5从下往上递推,需要开辟空间为n的数组,采用动态规划,2,3,5分别有三个索引,如果满足要求的数字等于2,3,5的倍数乘积,那么就直接将索引加1.

python代码:

class Solution:
    def nthUglyNumber(self, n):
        dp, index_two, index_three, index_five = [1] * n, 0, 0, 0
        for i in range(1, n):
            two = dp[index_two] * 2
            three = dp[index_three] * 3
            five = dp[index_five] * 5
            dp[i] = min(two, three, five)
            if two==dp[i]:
                index_two+=1
            if three==dp[i]:
                index_three+=1
            if five==dp[i]:
                index_five+=1
            print('==dp:', dp)
        return dp[-1]

n = 11
sol = Solution()
sol.nthUglyNumber(n)

c++代码:

class Solution {
public:
    int nthUglyNumber(int n) {
        vector<int> dp(n,1);
        int index_two=0;
        int index_three=0;
        int index_five=0;
        for (int i=1;i<n;i++){
            int two = dp[index_two]*2;
            int three = dp[index_three]*3;
            int five = dp[index_five]*5;
            dp[i] = min(min(two, three), five);
            if (dp[i]==two){
                index_two++;
            }
            if (dp[i]==three){
                index_three++;
            }
            if (dp[i]==five){
                index_five++;
            }
        }
        return dp[n-1];

    }
};

50.第一个只出现一次的字符

思路:

最直接的想法是hash,但是hash具有无序性,就改为字符数组计数

python代码:

class Solution:
    def firstUniqChar(self, s: str) -> str:
        letter_list = [0]*26
        for i in s:
            letter_list[ord(i) - ord('a')]+=1
        # print(letter_list)
        for i in s:
            if letter_list[ord(i)-ord('a')]==1:
                return i
        return " "

c++代码:

class Solution {
public:
    char firstUniqChar(string s) {
        vector<int> letter_list(26, 0);
        for(int i=0;i<s.size();i++)
        {
            letter_list[s[i]-'a']++;
        }
        vector<int>::iterator iter= letter_list.begin();
        for(int i=0;i<s.size();i++)
        {
            if (iter[s[i]-'a']==1)
            {
                return s[i];
            }
        }        
        return ' ';

    }
};

51.数组中的逆序对

思路1:两层for循环 超时

思路2:归并排序 在合并的时候顺便统计逆序对


class Solution:
    def mergeSort(self, nums, start, end):
        if start >= end:
            return
        mid = start + (end - start) // 2
        self.mergeSort(nums, start, mid)
        self.mergeSort(nums, mid + 1, end)
        self.merge(nums, start, mid, end)

    def merge(self, nums, start, mid, end):
        i, j, temp = start, mid + 1, []
        while i <= mid and j <= end:
            if nums[i] <= nums[j]:
                temp.append(nums[i])
                i += 1
            else:
                print('==i:', i)
                print('=== start:', start)
                print('=== mid:', mid)
                print('=== end:', end)
                self.cnt += mid - i + 1
                temp.append(nums[j])
                j += 1
        while i <= mid:
            temp.append(nums[i])
            i += 1
        while j <= end:
            temp.append(nums[j])
            j += 1
        for i in range(len(temp)):
            nums[start + i] = temp[i]
        print('==nums:', nums)
    def reversePairs(self, nums):
        self.cnt = 0
        self.mergeSort(nums, 0, len(nums) - 1)
        print('==after nums:', nums)
        return self.cnt


nums = [7,5,6,4]
sol = Solution()
sol.reversePairs(nums)
print(sol.cnt)

52.两个链表的第一个公共节点

思路:双指针 两个指针轮流走一遍各自的路程,这样相遇就是公共节点,对于没有公共节点的情况,所以需要判断自身节点不是none,而不是.next是none,在去交换指针,否则会陷入无穷循环,而此时输出就是none。

python

# 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) -> ListNode:
        first_head = headA
        second_head = headB
        while first_head !=second_head:
            if first_head is not None:
                first_head = first_head.next 
            else:
                first_head = headB
            if second_head is not None:
                second_head = second_head.next
            else:
                second_head = headA
        # print(first_head)
        return first_head

c++

/**
 * 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) {
    ListNode *first_node;
    first_node = headA;
    ListNode *second_node;
    second_node= headB;
    while(first_node != second_node)
    {
        if(first_node !=NULL)
        {
            first_node = first_node->next;
        }
        else
        {
            first_node = headB;
        }

        if(second_node !=NULL)
        {
            second_node = second_node->next;
        }
        else
        {
            second_node = headA;
        }
    }
    return first_node;
        
    }
};

53-1. 在排序数组中查找数字 I

思路1:hash

class Solution:
    def search(self, nums, target):
        dict_={}
        for i in range(len(nums)):
            dict_[nums[i]] = dict_.get(nums[i],0)+1
        print(dict_)
        return dict_[target] if target in dict_ else 0


nums = [5,7,7,8,8,10]
target = 8
sol = Solution()
sol.search(nums, target)

思路2:python 双指针

class Solution:
    def search(self, nums, target):
        left = 0
        right = len(nums)-1
        while left<right:
            middle = left+(right-left)//2
            if nums[middle] >=target:
                right=middle
            else:
                left=middle+1
        res=0
        for i in range(left,len(nums)):
            if nums[i]==target:
                res+=1
        return res

nums = [5,7,7,8,8,10]
target = 8
sol = Solution()
sol.search(nums, target)

思路2:C++ 双指针

#include <map>
#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

class Solution {
public:
    int search(vector<int>& nums, int target) {
        int left = 0;
        int right = nums.size()-1;
        int res=0;
        while (left<right)
        {
            int middle = left+(right-left)/2;
            if (nums[middle]>=target)
            {   
                right=middle;
            }
            else
            {
                left=middle+1;
            }
        }
        while (left<nums.size()&&nums[left]==target)
        {   
            left++;
            res++;
        }
        return res;
        
        
        return 0;
    }
};

int main()
{
    Solution *p = new Solution();
    vector<int> nums;
    nums = {5,7,7,8,8,10};
    int  target = 8;
    int res = p->search(nums, target);
    cout<<"==res:"<<res<<endl;
    delete p;
    p=NULL;
    return 0;
}

53-2.0~n-1中缺失的数字

思路:双指针,判断中值是否等于索引,等于的话说明缺失值在middle右边,left就变为middle+1,否则在middle左边,right变为middle-1,最后left的值就是缺失值. 

python代码

class Solution:
    def missingNumber(self, nums: List[int]) -> int:
        left = 0
        right = len(nums)-1
        while left<=right:
            middle =left+(right-left)//2
            if nums[middle]==middle:#中值等于索引 则说明缺失值在middle右边
                left = middle+1
            else:#中值不等于索引 则说明缺失值在middle左边
                right = middle-1
        return left

        
            

c++代码:

#include <vector>
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int left = 0;
        int right = nums.size()-1;
        while (left<=right)
        {
            int middle = left+(right-left)/2;
            if (nums[middle]==middle)
            {
                left = middle+1;
            }
            else
            {
                right = middle-1;
            }
        }
        return left;
    }
};
int main()
{
    Solution *p = new Solution();
    vector<int> nums;
    nums = {0,1,2,3,4,5,6,7,9};
    int res = p->missingNumber(nums);
    cout<<"==res:"<<res<<endl;
    delete p;
    p=NULL;
    return 0;
}

54.二叉搜索树的第k大节点

 思路:利用二叉搜索树特点,左子树值<根节点值<右子树值,故采用中序遍历

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def kthLargest(self, root: TreeNode, k: int) -> int:
        res = []
        def helper(node):
            if node is not None:
                helper(node.left)
                res.append(node.val)
                helper(node.right)
            
        helper(root)
        print('res:', res)
        return res[::-1][k-1]

c++代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    vector<int> res;
    void help(TreeNode* node)
    {
        if (node !=NULL)
        {
            help(node->left);
            res.push_back(node->val);
            help(node->right);
        }
    }
    int kthLargest(TreeNode* root, int k) {
        help(root);
        return res[res.size()-k];
    }
};

 55-1.二叉树的深度

递归:python代码

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        if not root:
            return 0
        return max(self.maxDepth(root.left),self.maxDepth(root.right))+1

c++代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root==NULL)
        {
            return 0;
        }
        return max(maxDepth(root->left),maxDepth(root->right))+1;

    }
};

 55-2.平衡二叉树

思路:前序遍历 求当前节点root的深度差,再去遍历求左右子节点的深度差

python代码

# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def help(self,node):#计算深度
        if node is None:
            return 0
        return max(self.help(node.left),self.help(node.right))+1
    def isBalanced(self, root: TreeNode) -> bool:
        if root is None:
            return True
        return abs(self.help(root.left) - self.help(root.right))<=1 and \
        self.isBalanced(root.left) and self.isBalanced(root.right)

c++代码:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    int help(TreeNode* node) 
    {
        if(node == NULL)
        {
            return 0;
        }
        return max(help(node->left),help(node->right))+1;
        
    }
    bool isBalanced(TreeNode* root) {
        if(root == NULL)
        {
            return true;
        }          
        return abs(help(root->left)-help(root->right))<=1 && isBalanced(root->left)&& isBalanced(root->right);

    }
};

56-1.数组中数字出现的次数

思路:hash

python代码:


class Solution:
    def singleNumbers(self, nums):
        dict_ = {}
        for i in range(len(nums)):
            dict_[nums[i]] = dict_.get(nums[i],0)+1
        print(dict_)
        res = []
        for key,value in dict_.items():
            if value==1:
                res.append(key)
        print(res)
        return res

nums = [4,1,4,6]
sol = Solution()
sol.singleNumbers(nums)

c++代码:

#include <map>
#include <vector>
#include <iostream>

using namespace std;

class Solution {
public:
    vector<int> singleNumbers(vector<int>& nums) {
        map<int,int>dict_;
        for (int k=0;k<nums.size();k++)
        {
            dict_[nums[k]]++;
        }
        vector<int> res;
        map<int,int>::iterator iter=dict_.begin();
        for (;iter!=dict_.end();iter++)
        {
            if(iter->second==1)
            {
                res.push_back(iter->first);
            }
        }
        return res;
    }
};


int main()
{
    vector<int> nums;
    nums = {4,1,4,6};
    Solution *sol = new Solution();
    // vector<int> res;
    auto res = sol->singleNumbers(nums);
    for (int k=0;k<res.size();k++)
    {
        cout<<"res[k]"<<res[k]<<endl;
    }
    delete sol;
    sol = NULL;
    return 0;
}

 56-2.数组中数字出现的次数 II

思路:hash

python代码:

class Solution:
    def singleNumber(self, nums: List[int]) -> int:
        dict_={}
        for num in nums:
            dict_[num]=dict_.get(num,0)+1
        # print(dict_)
        for key,value in dict_.items():
            if value==1:
                return key

c++代码:

#include <iostream>
#include <vector>
#include <list>
#include <map>
 
using namespace std;

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        // cout<<"hhah"<<endl;
        map<int,int> dict_;
        for (int k=0;k<nums.size();k++)
        {
            dict_[nums[k]]++;
        }
        map <int,int>::iterator itor = dict_.begin();
        for(;itor!=dict_.end();itor++)
        {
            // cout<<itor->first<<" "<<itor->second<<endl;
            if(itor->second==1){
                return itor->first;
            }
        }
        return -1;
    }
};


int main()
{   
    vector<int> nums;
    // int nums[] = {3,4,3,3};
    nums.push_back(3);
    nums.push_back(4);
    nums.push_back(3);
    nums.push_back(3);
    Solution  sol;
    int res = sol.singleNumber(nums);
    cout<<res<<endl;
    return 0;
}

57-1.和为s的两个数字

思路1:两层for循环 O(n2)


class Solution:
    def twoSum(self, nums, target):
        res = []
        for i in range(len(nums)):
            for j in range(i+1, len(nums)):
                if nums[i]+nums[j]==target:
                    res.extend([i, j])
                    break
        print('==res:', res)
        return res
nums = [2, 7, 6, 15]
target = 9
sol = Solution()
sol.twoSum(nums, target)

思路2:hash python代码


class Solution:
    def twoSum(self, nums, target):
        res_dict = {}
        for i in range(len(nums)):
            value = target - nums[i]
            if value in res_dict:
                return [res_dict[value], i]
            res_dict[nums[i]] = i
            print('==res_dict:', res_dict)
        return [-1, -1]


nums = [2, 7, 6, 15]
target = 9
sol = Solution()
res = sol.twoSum(nums, target)
print('res:', res)

思路2:c++代码:

#include <string>
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <typeinfo>

using namespace std;

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        map<int, int> dict_;
        for(int k=0;k<nums.size();k++)
        {
            dict_[nums[k]] = k;
        }
        map <int,int>::iterator iter = dict_.begin();
        for (;iter!=dict_.end();iter++)
        {
            if(dict_[target - iter->first])
            {
                // cout<<iter->second<<dict_[target - iter->first]<<endl;
                return {iter->first,target - iter->first};
            }
        }
        return {-1,-1};

    }
};

int main()
{   
    vector<int> nums;
    nums = {2,7,11,15};
    int target = 9;
    // nums = [2,7,11,15]
    Solution sol;
    vector<int> res;
    res = sol.twoSum(nums,target);
    for(int k=0;k<res.size();k++)
    {
        cout<<"==res[k]:"<<res[k]<<endl;
    }    
    return 0;
}

57-2.和为s的连续正数序列

思路:双指针,和偏大,左指针右移,和偏小,右指针右移,刚好的话就记录相应的值,左指针在右移停止循环即可。

python代码:


class Solution:
    def findContinuousSequence(self, target):
        list_ = [i for i in range(1, target)]
        print('==list_:', list_)
        left,right = 0, 0
        Sum = 0
        res = []
        while right<len(list_):
            if Sum<target:
                Sum+=list_[right]
                right+=1
            elif Sum == target:
                res.append(list_[left:right])
                left += 1
                Sum -= list_[left-1]
            else:
                Sum-=list_[left]
                left+=1
            print('==res:', res)
        return res


target = 9
sol = Solution()
sol.findContinuousSequence(target)

c++代码:

#include <map>
#include <vector>
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;

class Solution {
public:
    vector<vector<int>> findContinuousSequence(int target) {
        vector<int> nums;
        for (int i=1;i<target;i++)
        {
            nums.push_back(i);
        }
        int left=0;
        int right=0;
        int temp=0;
        vector<vector<int>> res;
        while (right<nums.size())
        {
            if(temp<target)
            {   
                temp+=nums[right];
                right++;                
            }
            else if(temp>target)
            {
                temp-=nums[left];
                left++;
            }
            else
            {   
                vector<int> res_temp;
                for (int i=left;i<right;i++)
                    {
                        res_temp.push_back(nums[i]);
                    } 
                res.push_back(res_temp);
                temp-=nums[left];
                left++;
            }
        }
        return res;
    }
};

int main()
{   
    Solution *p = new Solution();
    int target = 9;
    vector<vector<int>> res;
    res = p->findContinuousSequence(target);
    cout<<res.size()<<endl;
    for(int k=0;k<res.size();k++)
    {   
        for (int j=0;j<res[k].size();j++)
        {
            cout<<"res "<<k<<j<<" "<<res[k][j]<<endl;
        }
        
    }
    delete p;
    p = NULL;
    return 0;
}

58-1.翻转单词顺序

python代码:

class Solution:
    def reverseWords(self, s: str) -> str:
        s = s.strip()
        # print(s)
        s = s.split()
        # print(s)
        return ' '.join(s[::-1])

c++代码:

#include <map>
#include <vector>
#include <iostream>
#include <queue>
#include <string>
#include <algorithm>
using namespace std;

class Solution {
public:
    string reverseWords(string s) {
        string res="";
        int length = s.size();
        // cout<<"==length:"<<length<<endl;
        int right = length-1;
        while (right>=0)
        {
            if (s[right]==' ')//去除开头空格
            {
                right--;
                continue;
            }
            while (right>=0 && s[right]!= ' ')//减少至空格处
            {
                right--;
            }
            int index = right;
            right++;//加回去到非空格处
            if (res.empty())
            {
                while (s[right]!= ' ' && right<length)
                {   
                    res+=s[right];//第一个串 就开始添加
                    right++;
                }
            }
            else
            {
                res+=" ";
                while (s[right]!= ' ' && right<length)
                {   
                    res+=s[right];//第二个串以后 就先添加空格 在继续添加
                    right++;
                }
            }
            cout<<"res:"<<res<<endl;
            right = index;           
            
        }
        
        return res;
    }
};

int main()
{   
    Solution *p = new Solution();
    // string s = "the sky is blue";
    string s =  "  hello world!  ";
    string res;
    res = p->reverseWords(s);
    cout<<"res:"<<res<<endl;
    delete p;
    p = NULL;

    return 0;
}

 58-2.左旋转字符串

python代码:

class Solution:
    def reverseLeftWords(self, s: str, n: int) -> str:
        return s[n:]+s[:n]

c++代码:

class Solution {
public:
    string reverseLeftWords(string s, int n) {
        string res;
        for(int i=n;i<s.size();i++)
        {
            res+=s[i];
        }
        for(int i=0;i<n;i++)
        {
            res+=s[i];
        }
        return res;

    }
};

59-1.滑动窗口最大值

思路1.超时O(n*k)

class Solution:
    def maxSlidingWindow(self, nums, k):
        #时间复杂度O(Nk)超时了
        res = []
        for i in range(len(nums)-k+1):
            res.append(max(nums[i:i+k]))
        return res

思路1:c++可以:

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        if (nums.size()==0)
        {
            return res;
        }
        
        for (int i=0;i<nums.size()-k+1;i++)
        {   
            int temp = INT_MIN;
            for (int j=i;j<i+k;j++)
            {
                temp = max(temp, nums[j]);
            }
            res.push_back(temp);
        }
        return res;

    }
};

思路2:

动态规划:时间复杂度O(N)
1.将数组分成k+1个,剩下的一个可能不足; 
2.left数组存储每个拆分的从左到右的值,对于left来说每个块最右边元素最大;
3.right数组存储每个拆分的从右到左的值,对于right来说每个块最左边元素最大;
4.最后在利用left和right求最大值,max(left[i],right(j)) i每个块最右边元素索引,j每个块最左边元素索引

class Solution:
    def maxSlidingWindow(self, nums, k):
        n = len(nums)
        if n * k == 0:
            return []
        if k == 1:
            return nums

        left = [0] * n
        left[0] = nums[0]
        right = [0] * n
        right[n - 1] = nums[n - 1]
        for i in range(1, n):
            #从左往右
            if i%k==0:#分块的第一个元素
                left[i] = nums[i]
            else:
                left[i] = max(left[i-1],nums[i])
            # 从右往左
            j = n-i-1
            # 分块的最右边元素
            if (j+1) % k == 0:
                right[j] = nums[j]
            else:
                right[j] = max(right[j + 1], nums[j])
        print('===left:', left)
        print('===right:', right)

        #最后在利用left和right求最大值
        output = []
        for i in range(n - k + 1):
            output.append(max(left[i + k - 1], right[i]))

        return output

nums = [1,3,-1,-3,5,3,6,7]
k = 3
sol = Solution()
res = sol.maxSlidingWindow(nums, k)
print('res:', res)

思路3:双端队列:用一个队列一直存储更新最大值

# 双端队列:用一个队列一直存储更新最大值
class Solution:
    def maxSlidingWindow(self, nums, k):
        length = len(nums)
        if length == 0:
            return []
        res = []
        quene = []
        for j in range(length):
            i = j-k+1
            if i > 0 and quene[0] == nums[i-1]:#当要左移掉的元素等于quene头部元素,那么quene就移除头部元素
                quene.pop(0)
            while quene and quene[-1] < nums[j]:#保持quene里面都是单调递减的,且头部元素最大
                quene.pop()
            quene.append(nums[j])
            print('==quene:', quene)
            if i >= 0:
                res.append(quene[0])
        return res

nums = [1, 3, -1, -3, 5, 3, 6, 7]
k = 3
sol = Solution()
res = sol.maxSlidingWindow(nums, k)
print(res)

思路3:c++代码

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        vector<int> quene;
        for (int j=0;j<nums.size();j++)
        {   
            int i = j-k+1;
            if(i>0 && nums[i-1]==quene.front())//顶部元素正好等于了要左移元素 那么将队列顶部元素移动开
            {
                quene.erase(quene.begin());
            }
            while (!quene.empty() && quene.back()<nums[j])//保持单调递减
            {
                quene.erase(quene.end()-1);
            }            
            quene.push_back(nums[j]);
            // cout<<"quene.front():"<<quene.front()<<endl;
            // cout<<"quene.back():"<<quene.back()<<endl;
            if(i>=0)
            {
                res.push_back(quene.front());
            }
        }
        return res;

    }
};

59-2.队列的最大值

思路1: 其中去Max操作是o(n)


class MaxQueue:

    def __init__(self):
        self.quene = []

    def max_value(self):
        if len(self.quene):
            return max(self.quene)
        else:
            return -1

    def push_back(self, value):
        self.quene.append(value)


    def pop_front(self):
        if len(self.quene):
            return self.quene.pop(0)
        else:
            return -1

# Your MaxQueue object will be instantiated and called as such:
obj = MaxQueue()
param_1 = obj.max_value()
value = 10
obj.push_back(value)
param_3 = obj.pop_front()
print(param_3)

思路2:采用双端队列,优化取max操作


class MaxQueue:
    def __init__(self):
        self.queue = []
        self.deque = []
    def max_value(self):
        return self.deque[0] if self.deque else -1

    def push_back(self, value):
        self.queue.append(value)
        while self.deque and self.deque[-1] < value:
            self.deque.pop()
        self.deque.append(value)

    def pop_front(self):
        if len(self.queue) == 0:return -1
        val = self.queue.pop(0)
        if val == self.deque[0]:
            self.deque.pop(0)
        return val

obj = MaxQueue()
param_1 = obj.max_value()

for value in [10, 5, 8]:
    obj.push_back(value)

print('==obj.queue:', obj.queue)
print('==obj.deque:', obj.deque)
param_3 = obj.pop_front()
print('==param_3:', param_3)
print('==obj.queue:', obj.queue)
print('==obj.deque:', obj.deque)

60.n个骰子的点数

思路:一个骰子的概率 first_prob = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6]

两个骰子的概率 temp_prob = [5*2+1]

temp_prob[i+x] = first_prob[i]*second_prob[x]

第n个骰子的概率 temp_prob = [5*n+1]*0


#一个骰子的概率 first_prob = [1/6, 1/6, 1/6, 1/6, 1/6, 1/6]
#两个骰子的概率 temp_prob = [5*2+1]
# temp_prob[i+x] = first_prob[i]*second_prob[x]

#第n个骰子的概率 temp_prob = [5*n+1]*0
class Solution:
    def dicesProbability(self, n):
        first_prob, second_prob = [1/6]*6, [1/6]*6
        for index in range(2, n+1):
            temp_prob = [0]*(5*index+1)
            for i in range(len(first_prob)): #第一个骰子的概率
                for j in range(len(second_prob)): #第二个骰子的概率
                    temp_prob[i+j] += first_prob[i]*second_prob[j]
            print('==temp_prob:', temp_prob)
            #第一个骰子的概率换成前几次计算的概率也就是n-1
            first_prob = temp_prob
        print('==first_prob:', first_prob)
        return first_prob
n = 2
sol = Solution()
sol.dicesProbability(n)

c++代码:

class Solution {
public:
    vector<double> dicesProbability(int n) {
        vector<double> probs;
        vector<double> first_prob;
        for (int i=0;i<6;i++)
        {
            probs.push_back(1./6);
            first_prob.push_back(1./6);
        }
        for (int i=2;i<n+1;i++)
        {   
            vector<double> temp_prob;
            for (int temp_i=0;temp_i<5*i+1;temp_i++)
            {
                temp_prob.push_back(0);
            }
            for (int j=0;j<probs.size();j++)
            {
                for (int k=0;k<first_prob.size();k++)
                {
                    temp_prob[j+k]+=probs[j]*first_prob[k];
                }   
            }
            probs = temp_prob;
        }
        return probs;

    }
};

61.扑克牌中的顺子

思路:1.除去0发现重复的就返回false
2. 如果没有重复,则再判断除去的0的最大最小值差值与5的关系

python代码:

#思路:1.除去0发现重复的就返回false
#2. 如果没有重复,则再判断除去的0的最大最小值差值与5的关系

class Solution:
    def isStraight(self, nums):
        nums  = sorted(nums)
        index = 0
        for i in range(len(nums)-1):
            if nums[i]==0:
                index+=1
            elif nums[i] == nums[i+1]:#先去重
                return False
        if nums[-1]-nums[index]>4:
            return False
        return True


# nums = [0,0,1,2,5]
nums = [0,6,1,2,5]
sol = Solution()
res = sol.isStraight(nums)
print(res)

c++代码:

class Solution {
public:
    bool isStraight(vector<int>& nums) {
        int index = 0;
        sort(nums.begin(),nums.end());
        for(int i=0;i<nums.size();i++)
        {
            if (nums[i]==0)
            {
                index+=1;
            }
            else if(i>0 && nums[i]==nums[i-1])
            {
                return false;
            }
        }
        if(nums.back() - nums[index]>4)
        {   
            return false;
        }
        return true;

    }
};

62.圆圈中最后剩下的数字

思路:一直迭代

python代码:


#思路:一直迭代
class Solution:
    def lastRemaining(self, n, m):
        index = 0
        num_list = [i for i in range(n)]
        while len(num_list) > 1:
            print('==num_list:', num_list)
            index = (index + m-1) % len(num_list)
            print('==index:', index)
            num_list.pop(index)
        return num_list[0]

n = 4
m = 3
sol = Solution()
sol.lastRemaining(n, m)

c++代码:

上述代码改写成c++会超时,故换一种思路,从两个人一直往上递推到n个人

class Solution {
public:
    int lastRemaining(int n, int m) {
        int pos=0;
        for (int i=2;i<=n;i++)
        {
            pos = (pos+m)%i;
        }
        return pos;

    }
};

63.股票的最大利润

思路:一次遍历更新最小价格和利润即可 python代码

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices)==0:
            return 0
        min_price = prices[0]
        max_profit = 0
        for i in range(1,len(prices)):
            max_profit = max(max_profit, prices[i] - min_price)
            min_price = min(min_price, prices[i])
        # print(max_profit)
        return max_profit

dp:

class Solution:
    def maxProfit(self, prices: List[int]) -> int:
        if len(prices)==0:
            return 0
        dp =[0]*len(prices)
        min_price = prices[0]
        for i in range(1,len(prices)):
            dp[i] = max(dp[i-1],prices[i]-min_price)
            min_price = min(min_price,prices[i])
        # print(dp)
        return dp[-1]

c++代码:

class Solution {
public:
    int maxProfit(vector<int>& prices) {
        if(prices.size()==0){return 0;}
        int min_price = prices[0];
        int profit = 0;
        for(int i=1;i<prices.size();i++){
            profit = max(profit, prices[i]-min_price);
            min_price = min(min_price, prices[i]);
        }
        return profit;
    }
};

64.求1+2+…+n

python:

class Solution:
    def sumNums(self, n: int) -> int:
        return n if n==0 else n+self.sumNums(n-1)

c++:

class Solution {
public:
    int sumNums(int n) {
        if (n==1){return n;}
        return n+sumNums(n-1);

    }
};

65.不用加减乘除做加法

思路:既然不能用四则运算,那么就用位运算替代

class Solution {
public:
    int add(int a, int b) {
        if(a==0 || b==0){
            return a==0?b:a;
        }
        int sum_=0;
        int carry=0;
        while (b!=0)
        {
            sum_ = a^b;
            carry = (unsigned int) (a&b)<<1;
            a = sum_;
            b = carry;
        }
        return a;

    }
};

66.构建乘积数组

思路1:双指针:

超时

# 双层for循环 超时 o(n^2)
class Solution:
    def constructArr(self, a):
        n = len(a)
        res = [0]*n
        index = 0
        while index<n:
            temp = 1
            left = index-1
            right = index+1
            while left>=0:
                temp*=a[left]
                left-=1
            while right<n:
                temp *= a[right]
                right += 1
            res[index]= temp
            index+=1
        print(res)
        return res

思路2:dp 用left记录存储i的左半部分乘积

             用right记录存储i的右半部分乘积

         再用left和right对应位置的数相乘就是结果

#B[i] = A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n]
#dp left存储i的左半部分乘积
#dp right存储i的左半部分乘积
class Solution:
    def constructArr(self, a):
        n = len(a)
        left, right = [1] * n, [1] * n
        for i in range(1, n):
            left[i] = left[i - 1] * a[i - 1]
        print(left)
        for i in range(n-2, -1, -1):
            right[i] = right[i+1]*a[i+1]
        print(right)

        res = [0]*len(a)
        for i in range(n):
            res[i] = left[i]*right[i]
        print(res)
        return res
a = [1,2,3,4,5]
sol = Solution()
sol.constructArr(a)

思路3:优化上一个dp


#优化版
class Solution:
    def constructArr(self, a):
        n = len(a)
        left, right = [1] * n, [1] * n
        for i in range(1, n):
            left[i] = left[i - 1] * a[i - 1]
        print(left)

        temp = 1
        for i in range(n-2, -1, -1):
            temp = temp*a[i+1]
            left[i] *= temp
        print(left)
        return left

a = [1,2,3,4,5]
sol = Solution()
sol.constructArr(a)

c++:

class Solution {
public:
    vector<int> constructArr(vector<int>& a) {
        int n = a.size();
        vector<int>res(n,1);
        for (int i=1;i<n;i++){
            res[i] = res[i-1]*a[i-1];
        }
        int temp=1;
        for (int i=n-2;i>-1;i--){
            temp *= a[i+1];
            res[i] *= temp;
        }        
        return res;

    }
};

67.把字符串转换成整数

思路:

 1.去除首尾空格

2.判断符号索引

3.从符号索引的下一位进行转换 遇到字母就停止

#思路:
# 1.去除首尾空格
# 2.判断符号索引
# 3.从符号索引的下一位进行转换 遇到字母就停止
class Solution:
    def strToInt(self, str):
        new_str = str.strip()
        if len(new_str)==0:
            return 0
        start = 0
        sign = 1
        if new_str[0]=='-':
            start=1
            sign = -1
        if new_str[0]=='+':
            start=1
            sign = 1
        res = 0
        for i in range(start,len(new_str)):
            if "0"<=new_str[i]<="9":
               res = 10*res + int(new_str[i])
            else:
                break
        print(res)
        res  = sign*res
        if res >= 2 ** 31 - 1:
            return 2**31-1
        if res<=-2**31:
            return -2**31
        return res

str = "   -42ddff"
sol = Solution()
sol.strToInt(str)

c++:

class Solution {
public:
    int strToInt(string str) {
        int index =0;
        for (int i=0;i<str.size();i++){
            if (str[i]==' '){
                index++;
            }
            else{
                break;
            }
        }
        string new_str = "";
        new_str = str.substr(index);
        // cout<<new_str<<endl;
        int start=0;
        int sign=1;
        long res=0;
        if (new_str[0]=='-'){
            sign=-1;
            start=1;
        }
        if (new_str[0]=='+'){
            sign=1;
            start=1;
        }
        for(int i=start;i<new_str.size();i++){
            if('0'<=new_str[i] && new_str[i]<='9'){
                res=10*res+(new_str[i]-'0');
                if(sign==1 && res>INT_MAX){
                    return INT_MAX;
                }
                if(sign==-1 && res-1>INT_MAX){
                    return INT_MIN;
                }
            }
            else{
                break;
            }
        }
        res = sign*res;
        if (res>pow(2,31)-1){
            return pow(2,31)-1;
        }
        if (res<-pow(2,31)){
            return -pow(2,31);
        }
        return res;

    }
};

 68-1.二叉搜索树的最近公共祖先

思路:

1.从根节点开始遍历树
2.如果节点 p 和节点 q 都在右子树上,那么以右孩子为根节点继续 1 的操作
3.如果节点 p 和节点 q 都在左子树上,那么以左孩子为根节点继续 1 的操作
4.如果条件 2 和条件 3 都不成立,这就意味着我们已经找到p 和q 的公共祖先了

解法1:当成普通二叉树

# 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 root==p or root==q or root is None:
            return root
        
        left_node = self.lowestCommonAncestor(root.left,p,q)
        right_node = self.lowestCommonAncestor(root.right,p,q)
        if left_node is None:
            return right_node
        if right_node is None:
            return left_node
        return root

解法2利用二叉搜索树特点根节点值和左右子树值大小的特点.递归法

# 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':
        print('==root.val:', root.val)
        if root.val< min(p.val, q.val):#都大于根节点的值 将右孩子作为根节点
            return self.lowestCommonAncestor(root.right, p, q)
        elif root.val > max(p.val, q.val):#都小于根节点的值 将左孩子作为根节点
            return self.lowestCommonAncestor(root.left, p, q)
        else:#找到公共祖先
            return root
        

解法3.迭代法

#利用二叉搜索树的特点
class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
       node = root
       while node:
            if node.val < min(p.val,q.val):
               node = node.right
            elif node.val > max(p.val,q.val):
               node = node.left
            else:
                return node

c++:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if(root->val<min(p->val,q->val)){
            return lowestCommonAncestor(root->right,p,q);
        }
        if(root->val>max(p->val,q->val)){
            return lowestCommonAncestor(root->left,p,q);
        }
        return root;
    }
};

 68-2:二叉树的最近公共祖先

python:递归

# 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 root is None or root==p or root==q:#递归终止条件 节点为空 或者节点等于p,q其中之一
            return root
        left = self.lowestCommonAncestor(root.left, p, q)#遍历左子树
        right = self.lowestCommonAncestor(root.right, p, q)#遍历右子树
        if left is None:#左子树为空 就去右子树 
            return right
        if right is None:#右子树为空 就去左子树 
            return left
        return root#左右子树都不为空 说明找到了节点 

c++:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
        if (root == NULL){
            return NULL;
        }
        if(root->val == p->val || root->val == q->val){
            return root;
        }
        TreeNode* left_node = lowestCommonAncestor(root->left,p,q);
        TreeNode* right_node = lowestCommonAncestor(root->right,p,q);
        if(left_node !=NULL && right_node!=NULL){
            return root;
        }
        if (left_node==NULL){
            return right_node;
        }
        return left_node;
    }
};

猜你喜欢

转载自blog.csdn.net/fanzonghao/article/details/113822493
今日推荐