LeetCode Algorithm 0021 - 0025

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/darkrabbit/article/details/82927072

LeetCode Algorithm 0021 - 0025



0021 - Merge Two Sorted Lists (Easy)

Problem Link: https://leetcode.com/problems/merge-two-sorted-lists/description/

Description

Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.

Example:

Input: 1->2->4, 1->3->4
Output: 1->1->2->3->4->4

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/merge-two-sorted-lists/description/

namespace P21MergeTwoSortedLists
{
    struct ListNode
    {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(NULL)
        {
        }
    };

    class Solution
    {
        public:
        ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
        {
            ListNode* head = new ListNode(0);
            ListNode* current = head;

            ListNode* tmp1 = l1;
            ListNode* tmp2 = l2;
            ListNode* next = NULL;

            while (tmp1 != NULL || tmp2 != NULL)
            {
                if (tmp1 == NULL)
                {
                    next = new ListNode(tmp2->val);
                    tmp2 = tmp2->next;
                }
                else if (tmp2 == NULL)
                {
                    next = new ListNode(tmp1->val);
                    tmp1 = tmp1->next;
                }
                else
                {
                    if (tmp1->val < tmp2->val)
                    {
                        next = new ListNode(tmp1->val);
                        tmp1 = tmp1->next;
                    }
                    else
                    {
                        next = new ListNode(tmp2->val);
                        tmp2 = tmp2->next;
                    }
                }

                current->next = next;
                current = current->next;
            }

            current = head->next;
            head->next = NULL;
            delete head;
            return current;
        }
    };
}


0022 - Generate Parentheses (Medium)

Problem Link: https://leetcode.com/problems/generate-parentheses/description/

Description

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

[
  "((()))",
  "(()())",
  "(())()",
  "()(())",
  "()()()"
]

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/generate-parentheses/description/

namespace P22GenerateParentheses
{
    class Solution
    {
        public:
        vector<string> generateParenthesis(int n)
        {
            if (n <= 0)
            {
                return { "" };
            }

            vector<string> result = vector<string>();
            AddBacktrack(result, n, "", 0, 0);
            return result;
        }

        private:
        void AddBacktrack(vector<string>& result, int n, string s, int leftIndex, int rightIndex)
        {
            if (s.size() == 2 * n)
            {
                result.push_back(s);
                return;
            }

            if (leftIndex < n)
            {
                AddBacktrack(result, n, s + "(", leftIndex + 1, rightIndex);
            }

            if (rightIndex < leftIndex)
            {
                AddBacktrack(result, n, s + ")", leftIndex, rightIndex + 1);
            }
        }
    };
}


0023 - Merge k Sorted Lists (Hard)

Problem Link: https://leetcode.com/problems/merge-k-sorted-lists/description/

Description

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

Example:

Input:
[
  1->4->5,
  1->3->4,
  2->6
]
Output: 1->1->2->3->4->4->5->6

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/merge-k-sorted-lists/description/

namespace P23MergeKSortedLists
{
    struct ListNode
    {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(NULL)
        {
        }
    };

    class Solution
    {
        public:
        ListNode* mergeKLists(vector<ListNode*>& lists)
        {
            if (lists.empty())
            {
                return NULL;
            }

            int size = lists.size();
            vector<ListNode*> tmp = vector<ListNode*>(lists);

            // 使用二叉树方法 
            /*           0
            *            1    
            *          /   \
            *         2     3
            *        / \   / \
            *       4   5 6   7
            *      ...
            */
            for (int i = 1; i < size; i *= 2)
            {
                for (int j = 0; j < size - i; j += i * 2)
                {
                    // 每次整合左节点与右节点至根节点。即
                    // if (i == 1): merge(0, 1) -> merge(2, 3) -> merge(4, 5) -> merge(6, 7) ...
                    //             0+1
                    //             2+3
                    //             / \
                    //           4+5 6+7
                    //           ... ...
                    // if (i == 2): merge(0, 2) -> merge(4, 6) -> ...
                    //           0+1+2+3
                    //           4+5+6+7
                    //           /     \
                    //     8+9+10+11  12+13+14+15
                    //        ...        ...        
                    // if (i == 4): merge(0, 4) -> ...
                    //       0+1+2+3+4+5+6+7
                    //       8+9+10+11+12+13+14+15
                    //           ......
                    // if (i == ...): merge(0, ...)
                    // 结果为 0, 即 tmp[0]
                    tmp[j] = mergeTwoLists(tmp[j], tmp[j + i]);
                }
            }

            return tmp[0];
        }

        private:
        // 此函数见 problem 0021
        ListNode* mergeTwoLists(ListNode* l1, ListNode* l2)
        {
            ListNode* head = new ListNode(0);
            ListNode* current = head;

            ListNode* tmp1 = l1;
            ListNode* tmp2 = l2;
            ListNode* next = NULL;

            while (tmp1 != NULL || tmp2 != NULL)
            {
                if (tmp1 == NULL)
                {
                    next = new ListNode(tmp2->val);
                    tmp2 = tmp2->next;
                }
                else if (tmp2 == NULL)
                {
                    next = new ListNode(tmp1->val);
                    tmp1 = tmp1->next;
                }
                else
                {
                    if (tmp1->val < tmp2->val)
                    {
                        next = new ListNode(tmp1->val);
                        tmp1 = tmp1->next;
                    }
                    else
                    {
                        next = new ListNode(tmp2->val);
                        tmp2 = tmp2->next;
                    }
                }

                current->next = next;
                current = current->next;
            }

            current = head->next;
            head->next = NULL;
            delete head;
            return current;
        }
    };
}


0024 - Swap Nodes in Pairs (Medium)

Problem Link: https://leetcode.com/problems/swap-nodes-in-pairs/description/

Description

Given a linked list, swap every two adjacent nodes and return its head.

Example:

Given 1->2->3->4, you should return the list as 2->1->4->3.

Note:

  • Your algorithm should use only constant extra space.
  • You may not modify the values in the list’s nodes, only nodes itself may be changed.

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/swap-nodes-in-pairs/description/

namespace P24SwapNodesInPairs
{
    struct ListNode
    {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(NULL)
        {
        }
    };

    class Solution
    {
        public:
        ListNode* swapPairs(ListNode* head)
        {
            if (head == NULL || head->next == NULL)
            {
                return head;
            }

            ListNode* curHead = head->next;

            ListNode* left = NULL;
            ListNode* middleLeft = head;
            ListNode* middleRight = head->next;
            ListNode* right = NULL;

            while (middleLeft != NULL && middleRight != NULL)
            {
                right = middleRight->next;
                middleRight->next = middleLeft;
                middleLeft->next = right;
                if (left != NULL)
                {
                    left->next = middleRight;
                }
                left = middleLeft;

                middleLeft = right;
                middleRight = right == NULL ? NULL : right->next;
            }

            return curHead;
        }
    };
}


0025 - Reverse Nodes in k-Group (Hard)

Problem Link: https://leetcode.com/problems/reverse-nodes-in-k-group/description/

Description

Given a linked list, reverse the nodes of a linked list k at a time and return its modified list.

k is a positive integer and is less than or equal to the length of the linked list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is.

Example:

  • Given this linked list: 1->2->3->4->5
  • For k = 2, you should return: 2->1->4->3->5
  • For k = 3, you should return: 3->2->1->4->5

Note:

  • Only constant extra memory is allowed.
  • You may not alter the values in the list’s nodes, only nodes itself may be changed.

Solution C++

#pragma once

#include "pch.h"

// Problem: https://leetcode.com/problems/reverse-nodes-in-k-group/description/

namespace P25ReverseNodesInKGroup
{
    struct ListNode
    {
        int val;
        ListNode *next;
        ListNode(int x) : val(x), next(NULL)
        {
        }
    };

    class Solution
    {
        public:
        ListNode* reverseKGroup(ListNode* head, int k)
        {
            if (k < 2 || head == NULL || head->next == NULL)
            {
                return head;
            }

#if false // 单循环-交换
            ListNode* result = NULL;
            ListNode* last = NULL;
            ListNode* start = NULL;
            ListNode* previous = NULL;
            ListNode* swap = head;
            ListNode* next = NULL;

            int perLoop = k - 1;

            for (int i = 0;;i++)
            {
                // first loop done
                if (i == perLoop)
                {
                    result = start;
                }

                // next loop
                if (i % perLoop == 0)
                {
                    if (swap == NULL || swap->next == NULL)
                    {
                        break;
                    }
                    last = previous;
                    previous = swap;
                    start = swap;
                    swap = start->next;
                }
                // last loop
                else if (swap == NULL)
                {
                    ListNode* cur = reverseKGroup(start, i % perLoop + 1);
                    if (last != NULL)
                    {
                        last->next = cur;
                        return i >= perLoop ? result : start;
                    }
                    return cur;
                }

                next = swap->next;
                swap->next = start;
                start = swap;
                previous->next = next;
                if (last != NULL)
                {
                    last->next = start;
                }

                swap = next;
            }

            return result;
#endif

#if true // 分割-递归
            ListNode* tail = head;
            for (int i = 0; i < k - 1 && tail != NULL; i++)
            {
                tail = tail->next;
            }

            // 不够k个
            if (tail == NULL)
            {
                return head;
            }

            ListNode* nextHead = tail->next; // 下k个的起始节点
            tail->next = NULL; // 分离前k个
            reverseGroup(head); // 递归翻转前k个

            head->next = reverseKGroup(nextHead, k); // 翻转下k个并将结果衔接
            return tail;
#endif
        }

        private:
        // 递归翻转
        // 举例:  A -> B -> C -> D -> NULL
        // 传递:  A
        // 顺序过程 :顺序调用 ListNode* reverseHead = reverseGroup(B -> C -> D);
        // 逆序参数D:
        //           head->next == NULL // D->next == NULL,   return D
        // 逆序参数C:
        //           head->next->next = head; // C->D->next = C   
        //           head->next = NULL        // C->next = NULL
        //                     D -> C -> NULL <- C <- B <- A, return D
        // 逆序参数B:
        //                D -> C -> B -> NULL <- B <- A,      return D
        // 逆序参数A:
        //           D -> C -> B -> A -> NULL <- A,           return D
        ListNode* reverseGroup(ListNode* head)
        {
            if (head == NULL)
            {
                return NULL;
            }
            if (head->next == NULL)
            {
                return head;
            }
            ListNode* reverseHead = reverseGroup(head->next);
            head->next->next = head;
            head->next = NULL;
            return reverseHead;
        }
    };
}


猜你喜欢

转载自blog.csdn.net/darkrabbit/article/details/82927072