跳转至

141. 环形链表

class Solution {
public:
    bool hasCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast && fast->next){
            slow = slow->next;
            fast = fast->next->next;
            if(fast == slow){
                return true;
            }

        }
        return false;
    }
};
使用快慢指针,如果快慢指针汇合说明有环。

160. 相交链表

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* A = headA;
        ListNode* B = headB;
        while(A != B){
            A = A != NULL ? A ->next : headB;
            B = B != NULL ? B->next : headA;

        }
        return A;
    }
};
代码答案很精妙,双指针遍历两个链表,因为a+c+b == b+c+a,所以必然汇合。

124. 二叉树中的最大路径和

class Solution {
private:
    int ans;   //全局变量
    int dfs(TreeNode* node){
        if(node == NULL){
            return 0;
        }

        int l_val = dfs(node->left);
        int r_val = dfs(node->right);
        ans = max(ans, l_val + r_val + node->val);
        return max(max(l_val, r_val) + node->val, 0);   //注意这里要用0截断负收益
    }
public:
    int maxPathSum(TreeNode* root) {
        ans = INT_MIN;
        dfs(root);
        return ans;
    }
};
使用递归,返回的是顺着该节点往下的值,同时修改ans为/\的最大值。

226. 翻转二叉树

class Solution {
public:
    TreeNode* invertTree(TreeNode* root) {
        if(root == nullptr){
            return 0;
        }
        swap(root->left, root->right);
        invertTree(root->left);
        invertTree(root->right);
        return root;
    }
};
简单递归。

104. 二叉树的最大深度

class Solution {
public:
    int maxDepth(TreeNode* root) {
        if(root == nullptr){
            return 0;
        }
        int depth = 0;
        int l_depth = maxDepth(root->left);
        int r_depth = maxDepth(root->right);

        return max(l_depth, r_depth) + 1;
    }
};
同样递归计算左右子树,之后取max加1。

543. 二叉树的直径

class Solution {
public:
    int ans = 0;
    int diameterOfBinaryTree(TreeNode* root) {
        auto dfs = [&](this auto&& dfs, TreeNode* node){
            if(node == nullptr){
                return -1;
            }
            int l_len = dfs(node->left) + 1;
            int r_len = dfs(node->right) + 1;
            ans = max(ans, l_len + r_len);
            return max(l_len, r_len);
        };
        dfs(root);
        return ans;
    }
};
其实是最大路径和的简化版,相当于所有路的权重都为1。递归即可,这里学一下Lambda函数的写法,写一个dfs,递归算左右的直径,ans是加和。

142. 环形链表 II

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* fast = head;
        ListNode* slow = head;
        while(fast && fast->next){
            fast = fast->next->next;
            slow = slow->next;
            if(fast == slow){
                while(slow != head){
                    slow = slow->next;
                    head = head->next;
                }
                return slow;
            }
        }
        return nullptr;
    }
};
依旧快慢指针,在环形链表一的基础上,因为从slow出去的步数正好是从头开始到入口的步数,所以加一个判断即可步进到入口。

42. 接雨水

class Solution {
public:
    int trap(vector<int>& height) {
        int ans = 0, pre_max = 0, suf_max = 0;
        int left = 0, right = height.size() - 1;
        while(left < right){
            pre_max = max(pre_max, height[left]);
            suf_max = max(suf_max, height[right]);
            ans += pre_max > suf_max ? suf_max-height[right--] : pre_max-height[left++];
        }
        return ans;
    }
};
传统方法使用两个数组储存左右高度;这里使用左右双指针,因为只要一侧比另一侧高度小,就能确定他能装的水量,实现O(1)的空间复杂度。

283. 移动零

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int i0 = 0;
        for(int& x : nums){
            if(x){
                swap{x, nums[i0]};
                i0++;
            }
        }
    }
};
快慢指针。快指针遍历数组元素,慢指针是标志着空位,如果快指针检测到非零元素则交换至空位,然后慢指针右移一位。