LeetCode 力扣 刷题记录 热题 HOT 100(226,234,236,238,239)题目+算法分析+Cpp解答

GitHub链接:https://github.com/WilliamWuLH/LeetCode

如果你觉得不错可以 ⭐Star 和 Fork ❤

226.Invert Binary Tree

递归:

/**
 * 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* invertTree(TreeNode* root) {
        if(root == NULL)
            return root;
        TreeNode* temp = root->left;
        root->left = root->right;
        root->right = temp;
        if(root->left != NULL)
            invertTree(root->left);
        if(root->right != NULL)
            invertTree(root->right);
        return root;
    }
};

234.Palindrome Linked List

双指针(快慢指针)+ 反转后半部分链表:

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    bool isPalindrome(ListNode* head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast != NULL && fast->next != NULL){
            fast = fast->next->next;
            slow = slow->next;
        }
        ListNode* pre = NULL;
        while(slow != NULL){
            ListNode* temp = slow;
            slow = slow->next;
            temp->next = pre;
            pre = temp;
        }
        fast = head;
        while(pre != NULL){
            if(fast->val != pre->val)
                return false;
            fast = fast->next;
            pre = pre->next;
        }
        return true;
    }
};

236.Lowest Common Ancestor of a Binary Tree

递归 DFS + 公共前缀:

​ 思路很简单:先对两个结点进行深度优先搜索,并且记录搜索的路径,走左子树的话路径记录为 0,走右子树的话记录为 1,由此记录方式可以唯一并且准确记录从根结点到达目标结点的路径。

​ 然后再判断这两个目标结点的路径的公共前缀,即到达这两个目标结点必须经过的共同路径。

​ 找到它们的共同路径,在共同路径(公共前缀)的最后一个结点就-是这两个目标结点的最近公共祖先。

/**
 * 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) {
        vector<int> ppath, qpath;
        dfs(root, p, ppath);
        dfs(root, q, qpath);
        int len = min(ppath.size(), qpath.size());
        for(int i=0; i<len; i++){
            if(ppath[i] != qpath[i])
                break;
            if(ppath[i])
                root = root->right;
            else
                root = root->left;
        }
        return root;
    }
    bool dfs(TreeNode* root, TreeNode* target, vector<int> &path){
        if(root == target)
            return true;
        if(root != NULL){
            if(root->left != NULL){
                path.push_back(0);
                if( dfs(root->left, target, path) )
                    return true;
                path.pop_back();
            }
            if(root->right != NULL){
                path.push_back(1);
                if( dfs(root->right, target, path) )
                    return true;
                path.pop_back();
            }
        }
        return false;
    }
};

238.Product of Array Except Self

乘积 = 左边全部数的乘积 * 右边全部数的乘积:

​ 一趟循环,先算出左边全部数的乘积,再一趟循环回来,算出答案。

class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        vector<int> ans;
        int temp = 1;
        for(int i=0; i<nums.size(); i++){
            if(i == 0){
                ans.push_back(1);
                continue;
            }
            ans.push_back(ans[i-1]*nums[i-1]);
        }
        for(int i=nums.size()-2; i>=0; i--){
            temp *= nums[i+1];
            ans[i] *= temp;
        }
        return ans;
    }
};

239.Sliding Window Maximum

双端队列:

​ 为什么选择双端队列?

​ 既可以弹出队首元素,也可以弹出队尾元素,也可以在队尾插入元素,也可以访问队首元素。

​ 在双端队列中维持一个数组值单调递减的队列,队列中的元素必须都在窗口中,并且队首元素就是最大值,第二个就是第二大的值,以此类推。

​ 每次来一个元素,判断这个元素应该在这个双端队列的什么位置,从双端队列的队尾开始判断,比它小的都要弹出队列,直到找到比它大的或者是队列为空了,把此时的这个元素插入队列中。

​ 并且需要判断此时的队首是否还在新窗口中,即此时的最大值是否还合法,不合法(不在窗口中)就必须弹出。

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> ans;
        deque<int> dq;
        int len = nums.size();
        for(int i=0; i<len; i++){
            while(!dq.empty()){
                if(dq.front() <= i-k)
                    dq.pop_front();
                else if(nums[ dq.back() ] < nums[i])
                    dq.pop_back();
                else
                    break;
            }
            dq.push_back(i);
            if(i+1 >= k)
                ans.push_back(nums[ dq.front() ]);
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/qq_43413123/article/details/105918932
今日推荐