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;
}
};
}