DailyPractice.2023.10.19

1. 24. 两两交换链表中的节点

24. 两两交换链表中的节点

/**
 * 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* swapPairs(ListNode* head) {
        auto dummy = new ListNode();
        dummy -> next = head;
        auto cur = dummy;
        auto node1 = head;
        while (node1 && node1 -> next) {
            
            auto node2 = node1 -> next;
            auto node3 = node2 -> next;

            cur -> next = node2;
            node2 -> next = node1;
            node1 -> next = node3
            
            cur = node1;
            node1 = node3;
        }
        return dummy -> next;
    }
};
时间复杂度:O(n),其中 n 是链表的节点数量。需要对每个节点进行更新指针的操作。

空间复杂度:O(1)

在这里插入图片描述

2. 23. 合并 K 个升序链表

23. 合并 K 个升序链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode *a, ListNode *b) {
        if ((!a) || (!b)) return a ? a : b;
        ListNode head, *tail = &head, *aPtr = a, *bPtr = b;
        while (aPtr && bPtr) {
            if (aPtr -> val < bPtr -> val) {
                tail -> next = aPtr;
                aPtr = aPtr -> next;
            }
            else {
                tail->next = bPtr;
                bPtr = bPtr->next;
            }
            tail = tail -> next;
        }
        tail -> next = (aPtr ? aPtr : bPtr);
        return head.next;
    }
    ListNode* merge(vector<ListNode*> &lists,int l,int r) {
        if (l == r) return lists[l];
        if (l > r) return nullptr;
        int mid = (l + r) >> 1;
        return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
    }
    ListNode* mergeKLists(vector<ListNode*>& lists) {
        return merge(lists, 0, lists.size() - 1);
    }
};

时间复杂度:O(kn×log⁡k)
空间复杂度:递归会使用到 O(log⁡k)空间代价的栈空间。

3.148. 排序链表

3.148. 排序链表

/**
 * 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* sortList(ListNode* head) {
        return mergeSort(head);
    }
    ListNode* mergeSort(ListNode* head) {
        if (!head || !head -> next) return head;
        ListNode* mid = findMid(head);
        ListNode* l1 = head;
        ListNode* l2 = mid -> next;
        mid -> next = nullptr;
        l1 = mergeSort(l1);
        l2 = mergeSort(l2);
        return merge(l1,l2);
    }
    ListNode* findMid(ListNode* head) {
        ListNode* slow = head,*fast = head;
        while (fast -> next && fast -> next -> next) {
            slow = slow -> next;
            fast = fast -> next -> next;
        }
        return slow;
    }
    ListNode* merge(ListNode* l1, ListNode* l2) {
        ListNode* dummyHead = new ListNode();
        ListNode* cur = dummyHead;
        while (l1 && l2) {
            if (l1 -> val <= l2 -> val) {
                cur -> next = l1;
                l1 = l1 -> next;
            }
            else {
                cur->next = l2;
                l2 = l2->next;
            }
            cur = cur -> next;
        }
        cur -> next = l1 ? l1 : l2;
        return dummyHead -> next;
    }
};

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

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

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

/**
 * 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 == nullptr || root == p || root == q) return root;
        TreeNode *left = lowestCommonAncestor(root->left, p, q);
        TreeNode *right = lowestCommonAncestor(root->right, p, q);
        if (left == nullptr) return right;
        if (right == nullptr) return left;
        return root;
    }
};

时间复杂度 O(N): 其中 N为二叉树节点数;最差情况下,需要递归遍历树的所有节点。
空间复杂度 O(N): 最差情况下,递归深度达到 N ,系统使用 O(N)大小的额外空间。

5.78. 子集

78. 子集

class Solution {
public:
vector<vector<int>> res;
vector<int> path;
    vector<vector<int>> subsets(vector<int>& nums) {
       backtrack(0,nums);
       return res;
    }
    void backtrack(int start,vector<int>& nums) {
        res.push_back(path);

        for (int i = start; i < nums.size(); i++) {
            path.push_back(nums[i]);
            backtrack(i + 1,nums);
            path.pop_back();
        }
    }
};

6.138. 随机链表的复制

6.138. 随机链表的复制

/*
// 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:
    Node* copyRandomList(Node* head) {
        if (head == nullptr) return nullptr;
        Node* cur = head;
        unordered_map<Node*, Node*> map;
        while (cur != nullptr) {
            map[cur] = new Node(cur->val);
            cur = cur->next;
        }
        cur = head;
        while (cur) {
            map[cur] -> next = map[cur -> next];
            map[cur]->random = map[cur->random];
            cur = cur->next;
        }
        return map[head];
    }
};

时间复杂度:O(n),其中 n 是链表的长度。对于每个节点,我们至多访问其「后继节点」和「随机指针指向的节点」各一次,均摊每个点至多被访问两次。

空间复杂度:O(n),其中 n 是链表的长度。为哈希表的空间开销。

7.25. K 个一组翻转链表

7.25. K 个一组翻转链表

/**
 * 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* reverseKGroup(ListNode* head, int k) {
        ListNode* ans = new ListNode();
        ListNode* cur = ans;
        stack<ListNode*> s;
        while (head) {
            s.push(head);
            head = head -> next;
            if (s.size() == k) {
                 while (s.size()) {
                     cur -> next = s.top();
                     s.pop();
                     cur = cur -> next;
                 }
                cur -> next = nullptr;
            }
        }
        while(s.size()) {
            cur -> next = s.top();
            s.pop();
        }
        return ans -> next;
    }
};
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值