• DailyPractice.2023.10.14


    1.[53. 最大子数组和]

    53. 最大子数组和

    class Solution {
    public:
        int maxSubArray(vector<int>& nums) {
            // 1. dp[i] 包括下标i(以nums[i]为结尾)的最大连续子序列和为dp[i]
            // 2. dp[i] = max(nums[i],dp[i - 1] + nums[i]);  dp[i - 1] + nums[i],即:nums[i]加入当前连续子序列和
            // nums[i],即:从头开始计算当前连续子序列和
            // 3.  从递推公式可以看出来dp[i]是依赖于dp[i - 1]的状态,dp[0]就是递推公式的基础。
            // 4. 1 - n
            // 5. 方程
            if (nums.size() == 0) return 0;
         
            vector<int> dp(nums.size(),0);
            
            dp[0] = nums[0];
            int result = dp[0];
            for (int i = 1; i < nums.size(); i++) {
                dp[i] = max(dp[i - 1] + nums[i],nums[i]);
                if (result < dp[i]) {result = dp[i];}
            }
            return result;
        } 
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    时间复杂度: O ( N ) O(N) O(N)
    空间复杂度: O ( 1 ) O(1) O(1)

    2.[142. 环形链表 II]

    142. 环形链表 II

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode *detectCycle(ListNode *head) {
            ListNode* fast = head;
            ListNode* slow = head;
            if (head == nullptr || head -> next == nullptr)  return nullptr;
            while (fast && fast -> next) {
                fast = fast -> next -> next;
                slow = slow -> next;
                if (fast == slow) {
                    ListNode* index1 = slow;
                    ListNode* index2 = head;
                    while (index1 != index2) {
                        index1 = index1 -> next;
                        index2 = index2 -> next;
                    }
                    return index2;
            }
            
        }
        return nullptr;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

    时间复杂度: O ( N ) O(N) O(N)
    空间复杂度: O ( 1 ) O(1) O(1)

    3.[2. 两数相加]

    2. 两数相加

    /**
    /**
     * 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* dummy = new ListNode(-1);
            ListNode* cur = dummy;
            ListNode* cur1 = l1;
            ListNode* cur2 = l2;
            int t = 0;
            while (cur1 || cur2 || t) {
                if (cur1) {
                    t += cur1 -> val;
                    cur1 = cur1 -> next;
                }
                if (cur2) {
                    t += cur2->val;
                    cur2 = cur2 -> next;
                }
                cur -> next = new ListNode(t % 10);
                cur = cur -> next;
                t /= 10;
    
            }
            return dummy -> next;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    时间复杂度: O ( m a x ( m , n ) ) O(max(m,n)) O(max(m,n)),其中 m和 n分别为两个链表的长度。我们要遍历两个链表的全部位置,而处理每个位置只需要 O(1) 的时间。
    空间复杂度: O ( 1 ) O(1) O(1)

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

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

    /**
     * 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) {
            if (head == nullptr || n == 0) return nullptr;
    
            ListNode* dummy = new ListNode(-1);
            dummy -> next = head;
            ListNode* x = findListNode(dummy,n + 1);
            x -> next = x -> next -> next;
            return dummy -> next;
        }
        ListNode* findListNode(ListNode* head,int k) {
            ListNode* slow = head;
            ListNode* fast = head;
            while (k -- && fast) {
                fast = fast -> next;
            }
            while (fast) {
                slow = slow -> next;
                fast = fast -> next;
            }
            return slow;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    时间复杂度: O ( L ) O(L) O(L),其中 L 是链表的长度。
    空间复杂度: O ( 1 ) O(1) O(1)

    5.[21. 合并两个有序链表]

    21. 合并两个有序链表

    lass Solution {
    public:
        ListNode* mergeTwoLists(ListNode* list1, ListNode* list2) {
            if (list1 == nullptr) return list2;
            if (list2 == nullptr) return list1;
            ListNode* dummy = new ListNode(-1);
            ListNode* cur = dummy;
            ListNode* cur1 = list1;
            ListNode* cur2 = list2;
            while (cur1 && cur2) {
                if (cur1 -> val > cur2 -> val) {
                    cur -> next = cur2;
                    cur2 = cur2 -> next;
                }
                else {
                    cur -> next = cur1;
                    cur1 = cur1 -> next;
                }
                cur = cur -> next;
            }
            if (cur1) cur -> next = cur1;
            if (cur2) cur -> next = cur2;
            return dummy -> next;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    时间复杂度: O ( n + m ) O(n+m) O(n+m),其中 n 和 m 分别为两个链表的长度。因为每次循环迭代中,l1 和 l2 只有一个元素会被放进合并链表中, 因此 while 循环的次数不会超过两个链表的长度之和。所有其他操作的时间复杂度都是常数级别的,因此总的时间复杂度为 O(n+m)。

    空间复杂度: O ( 1 ) O(1) O(1)。我们只需要常数的空间存放若干变量。

    6.[102. 二叉树的层序遍历]

    102. 二叉树的层序遍历

    /**
     * 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:
        vector<vector<int>> levelOrder(TreeNode* root) {
            vector<vector<int>> res;
            queue<TreeNode*> q;
            if (root == nullptr) return res;
            q.push(root);
            while (q.size()) {
                vector<int> temp;
                int size = q.size();
                for (int i = 0; i < size; i++) {
                    auto t = q.front();
                    temp.push_back(t -> val);
                    q.pop();
                    if (t -> left) q.push(t -> left);
                    if (t -> right) q.push(t -> right);
                }
                res.push_back(temp);
            }
            return res;
         }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 时间复杂度 O(N) : N 为二叉树的节点数量,即 BFS 需循环 N 次。
    • 空间复杂度 O(N) : 最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N)大小的额外空间。

    7.[104. 二叉树的最大深度]

    104. 二叉树的最大深度

    /**
     * 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 maxDepth(TreeNode* root) {
            if(root == nullptr) return 0;
            return max(maxDepth(root -> left),maxDepth(root -> right)) + 1;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 时间复杂度 O(N) : N 为二叉树的节点数量,即 BFS 需循环 N 次。
    • 空间复杂度 O(N) : 最差情况下,即当树为平衡二叉树时,最多有 N/2 个树节点同时在 queue 中,使用 O(N)大小的额外空间。

    8.[17. 电话号码的字母组合]

    17. 电话号码的字母组合

    class Solution {
    public:
    const string letterMap[10] = {
            "", // 0
            "", // 1
            "abc", // 2
            "def", // 3
            "ghi", // 4
            "jkl", // 5
            "mno", // 6
            "pqrs", // 7
            "tuv", // 8
            "wxyz", // 9
    };
    vector<string> result;
    string s;
        void process(int index,string digits) {
            if (index == digits.size()) {
                result.push_back(s);
                return ;
            }
            int digit = digits[index] - '0';
            string letters = letterMap[digit];
            for (int i = 0; i < letters.size(); i++) {
                s.push_back(letters[i]);
                process(index + 1,digits);
                s.pop_back();
            }
        }
        vector<string> letterCombinations(string digits) {
            if (digits.size() == 0) {
                return result;
            }
            process(0,digits);
            return result;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    时间复杂度: O ( 3 m × 4 n ) O(3^m×4^n) O(3m×4n)

    空间复杂度: O ( m + n ) O(m+n) O(m+n),其中 m 是输入中对应 3 个字母的数字个数,n 是输入中对应 4 个字母的数字个数,m+n是输入数字的总个数。除了返回值以外,空间复杂度主要取决于哈希表以及回溯过程中的递归调用层数,哈希表的大小与输入无关,可以看成常数,递归调用层数最大为 m+n。

    9.[46. 全排列]

    46. 全排列

    class Solution {
    public:
    vector<vector<int>> res;
    vector<int> path;
        void process(int index,vector<int>& nums,vector<bool> &used) {
            if (path.size() == nums.size()) {
                res.push_back(path);
                return;
            }
            for (int i = 0; i < nums.size(); i++) {
                if (used[i] == false) {
                    used[i] = true;
                    path.push_back(nums[i]);
                    process(index + 1,nums,used);
                    used[i] = false;
                    path.pop_back();
                }
            }
        }
        vector<vector<int>> permute(vector<int>& nums) {
            if (nums.size() == 0) return res;
            vector<bool> used(nums.size(),false);
            process(0,nums,used);
            return res;
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    时间复杂度: O ( N ! N ) O(N!N) O(N!N): N为数组 nums 的长度;时间复杂度和数组排列的方案数成线性关系,即复杂度为 O(N!);数组拼接操作 join() 使用 O(N);因此总体时间复杂度为 O(N!N) 。
    空间复杂度: O ( N ) O(N) O(N) : 全排列的递归深度为 N ,系统累计使用栈空间大小为 O(N) 。

  • 相关阅读:
    产品经理常用软件汇总
    apache log4j漏洞复现
    解决 VMware Network Adapter VMnet1 IP 地址冲突导致无法打开路由器管理页面
    Python:Excel自动化实践入门篇 乙【送图书活动继续】
    Docker Cgroups资源控制
    【数据结构】——链表面试题详解
    重读百度移动生态:“第一曲线”的创新“延长线”
    网络协议常用面试题汇总(一)
    什么是 Linux 进程、线程、轻量级进程和进程状态
    Opencv中goodFeaturesToTrack函数(Harris角点、Shi-Tomasi角点检测)算子速度的进一步优化(1920*1080测试图11ms处理完成)。
  • 原文地址:https://blog.csdn.net/weixin_54447296/article/details/133828758