Tsai笔记:LeetCode笔记(1)—— 链表
一、相关题型
-
1. 找出两个链表的交点
-
2. 链表反转
-
3. 归并两个有序的链表
-
4. 从有序链表中删除重复节点
-
5. 删除链表的倒数第 n 个节点
-
6. 交换链表中的相邻结点
-
7. 链表求和 I
-
8. 链表求和 II
-
9. 回文链表
-
10. 分隔链表
-
11. 链表元素按奇偶聚集
二、 相关代码
#include <iostream>
#include <stack>
#include <vector>
using namespace std;
class ListNode {
public:
int val;
ListNode* next;
ListNode(int v) : val(v), next(nullptr){}
};
class Solution {
public:
//1. 找出两个链表的交点
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
//1.若其中一个为nullptr说明没有交点
if (headA == nullptr || headB == nullptr) {
return nullptr;
}
//2.用两个指针将headA和headB遍历
ListNode *List1 = headA, *List2 = headB;
while (List1 != List2)
{
List1 = List1 != nullptr ? List1->next : headB;
List2 = List2 != nullptr ? List2->next : headA;
}
return List1;
}
//2. 链表反转
ListNode* reverseList(ListNode* head) {
//1.若为nullptr或者next为nullptr直接返回head就行
if (head == nullptr || head->next == nullptr) {
return head;
}
//2.需要三个指针pre,curr,next
ListNode *pre = nullptr, *curr = head, *next = nullptr;
while (curr != nullptr) {
next = curr->next;
curr->next = pre;
pre = curr;
curr = next;
}
return pre;
}
//3. 归并两个有序的链表
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
//1.若l1或l2为nullptr直接返回另一个
if (l1 == nullptr)
return l2;
if (l2 == nullptr)
return l1;
//2.比较大小递归求解
if (l1->val < l2->val)
{
l1->next = mergeTwoLists(l1->next, l2);
return l1;
}
else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
//4. 从有序链表中删除重复节点
ListNode* deleteDuplicates(ListNode* head) {
//1.若为nullptr或者next为nullptr直接返回head就行
if (head == nullptr || head->next == nullptr)
return head;
//2.
ListNode *tmp = head;
while (tmp->next != nullptr) {
if (tmp->val != tmp->next->val)
tmp = tmp->next;
else {
ListNode *del = tmp->next;
tmp->next = tmp->next->next;
delete del;
}
}
return head;
}
//5. 删除链表的倒数第 n 个节点
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *fast = head, *slow = head;
while (n-- > 0)
fast = fast->next;
if (fast == nullptr)
return head->next;
while (fast->next != nullptr)
{
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return head;
}
//6. 交换链表中的相邻结点
ListNode* swapPairs(ListNode* head) {
ListNode *pre = new ListNode(0);
pre->next = head;
head = pre;
while (pre->next != nullptr && pre->next->next != nullptr) {
ListNode *curr = pre->next, *next = pre->next->next;
pre->next = next;
curr->next = next->next;
next->next = curr;
pre = pre->next->next;
}
return head->next;
}
//7. 链表求和 I
ListNode* addTwoNumbers_I(ListNode* l1, ListNode* l2) {
int count = 0;
ListNode *root = new ListNode(-1);
ListNode *curr = root;
while (l1 != nullptr || l2 != nullptr || count != 0) {
int x = 0;
if (l1 != nullptr) {
x = l1->val;
l1 = l1->next;
}
int y = 0;
if (l2 != nullptr) {
y = l2->val;
l2 = l2->next;
}
int sum = x + y + count;
ListNode *next = new ListNode(sum % 10);
curr->next = next;
curr = curr->next;
count = sum / 10;
}
return root->next;
}
//8. 链表求和 II
ListNode* addTwoNumbers_II(ListNode* l1, ListNode* l2) {
//1.获取将两个链表压入两个栈中
stack<int> stack1;
while (l1 != nullptr) {
stack1.push(l1->val);
l1 = l1->next;
}
stack<int> stack2;
while (l2 != nullptr) {
stack2.push(l2->val);
l2 = l2->next;
}
ListNode *next = new ListNode(-1);
//2.取出栈中的元素相加作为新节点
int count = 0;
while (!stack1.empty() || !stack2.empty() || count != 0){
int x = 0;
if (!stack1.empty()) {
x = stack1.top();
stack1.pop();
}
int y = 0;
if (!stack2.empty()) {
y = stack2.top();
stack2.pop();
}
int sum = x + y + count;
ListNode *curr = new ListNode(sum % 10);
curr->next = next->next;
next->next = curr;
count = sum / 10;
}
return next->next;
}
//9. 回文链表
bool isPalindrome(ListNode* head) {
//1.使用快慢指针找到链表的另一个开端
ListNode *fast = head, *slow = head;
while (fast) {//find mid node
slow = slow->next;
fast = fast->next ? fast->next->next : fast->next;
}
//2.翻转后部分的链表
ListNode *prev = nullptr, *next;
while (slow != nullptr) {
next = slow->next;
slow->next = prev;
prev = slow;
slow = next;
}
//3.比较两段是否相同
while (prev != nullptr) {
if (head->val != prev->val)
return false;
head = head->next;
prev = prev->next;
}
return true;
}
//10. 分隔链表
vector<ListNode*> splitListToParts(ListNode* root, int k) {
//1.遍历链表得到其长度
int Len = 0;
ListNode *tmp = root;
while (tmp != nullptr) {
Len++;
tmp = tmp->next;
}
//2.得到每个子链表平均元素的个数和余数,并将vector分为k份
int avelen = Len / k;
int Lev = Len % k;
vector<ListNode *> result(k, nullptr);
//3.对k段进行分配
for (int i = 0; i < k; i++) {
result[i] = root;
int Childlen = Lev ? (avelen + 1) : avelen;
for (int j = 0; j < Childlen - 1; j++) {
root = root->next;
}
if (root) {
ListNode *tmp = root->next;
root->next = nullptr;
root = tmp;
}
if (Lev) Lev--;
}
return result;
}
//11. 链表元素按奇偶聚集
ListNode* oddEvenList(ListNode* head) {
//1.若head为nullptr直接返回
if (head == nullptr)
return head;
//2.三个指针odd、even、还有一个保存even的开始
ListNode *odd = head, *even = head->next, *evenhead = head->next;
while (even != nullptr && even->next != nullptr) {
odd->next = odd->next->next;
odd = odd->next;
even->next = even->next->next;
even = even->next;
}
odd->next = evenhead;
return head;
}
};
int main()
{
//2. 链表反转
const int a = 6;
int A[a] = { 2,2,4,4,6,7 };
ListNode *listA = new ListNode(A[0]);
ListNode *addA = listA;
int i = 1;
while (i < a) {
ListNode *tmp = new ListNode(A[i]);
addA->next = tmp;
addA = addA->next;
i++;
}
Solution obj;
ListNode *res = obj.reverseList(listA);
std::cout << "<<< 2. 链表反转 >>>" << std::endl;
while (res != nullptr) {
std::cout << res->val << "->";
res = res->next;
}
std::cout << "nullptr" << std::endl;
3. 归并两个有序的链表
//const int a = 5, b = 6;
//int A[a] = { 1,3,5,7,9 };
//int B[b] = { 2,4,6,8,10,12 };
//ListNode *listA = new ListNode(A[0]);
//ListNode *listB = new ListNode(B[0]);
//int i = 1;
//ListNode *addA = listA, *addB = listB;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//i = 1;
//while (i < b) {
// ListNode *tmp = new ListNode(B[i]);
// addB->next = tmp;
// addB = addB->next;
// i++;
//}
//Solution obj;
//ListNode *result = obj.mergeTwoLists(listA, listB);
//std::cout << "<<< 3. 归并两个有序的链表 >>>" << std::endl;
//while (result != nullptr) {
// std::cout << result->val << "->";
// result = result->next;
//}
//std::cout << "nullptr" << std::endl;
4. 从有序链表中删除重复节点
//const int a = 6;
//int A[a] = { 2,2,4,4,6,7 };
//ListNode *listA = new ListNode(A[0]);
//ListNode *addA = listA;
//int i = 1;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//Solution obj;
//ListNode *result = obj.deleteDuplicates(listA);
//std::cout << "<<< 4. 从有序链表中删除重复节点 >>>" << std::endl;
//while (result != nullptr) {
// std::cout << result->val << "->";
// result = result->next;
//}
//std::cout << "nullptr" << std::endl;
5. 删除链表的倒数第 n 个节点
//const int a = 6;
//int A[a] = { 2,2,6,6,10,12 };
//ListNode *listA = new ListNode(A[0]);
//ListNode *addA = listA;
//int i = 1;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//Solution obj;
//ListNode *result = obj.removeNthFromEnd(listA, 3);
//std::cout << "<<< 5. 删除链表的倒数第 n 个节点 >>>" << std::endl;
//while (result != nullptr) {
// std::cout << result->val << "->";
// result = result->next;
//}
//std::cout << "nullptr" << std::endl;
6. 交换链表中的相邻结点
//const int a = 6;
//int A[a] = { 2,3,4,5,6,7 };
//ListNode *listA = new ListNode(A[0]);
//ListNode *addA = listA;
//int i = 1;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//Solution obj;
//ListNode *result = obj.swapPairs(listA);
//std::cout << "<<< 6. 交换链表中的相邻结点 >>>" << std::endl;
//while (result != nullptr) {
// std::cout << result->val << "->";
// result = result->next;
//}
//std::cout << "nullptr" << std::endl;
7. 链表求和 I
//const int a = 3, b = 3;
//int A[a] = { 2,4,3 };
//int B[b] = { 5,6,4 };
//ListNode *listA = new ListNode(A[0]);
//ListNode *listB = new ListNode(B[0]);
//int i = 1;
//ListNode *addA = listA, *addB = listB;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//i = 1;
//while (i < b) {
// ListNode *tmp = new ListNode(B[i]);
// addB->next = tmp;
// addB = addB->next;
// i++;
//}
//Solution obj;
//ListNode *result = obj.addTwoNumbers_I(listA, listB);
//std::cout << "<<< 7. 链表求和 I >>>" << std::endl;
//while (result != nullptr) {
// std::cout << result->val << "->";
// result = result->next;
//}
//std::cout << "nullptr" << std::endl;
8. 链表求和 II
//const int a = 4, b = 3;
//int A[a] = { 7,2,4,3 };
//int B[b] = { 5,6,4 };
//ListNode *listA = new ListNode(A[0]);
//ListNode *listB = new ListNode(B[0]);
//int i = 1;
//ListNode *addA = listA, *addB = listB;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//i = 1;
//while (i < b) {
// ListNode *tmp = new ListNode(B[i]);
// addB->next = tmp;
// addB = addB->next;
// i++;
//}
//Solution obj;
//ListNode *result = obj.addTwoNumbers_II(listA, listB);
//std::cout << "<<< 8. 链表求和 II >>>" << std::endl;
//while (result != nullptr) {
// std::cout << result->val << "->";
// result = result->next;
//}
//std::cout << "nullptr" << std::endl;
9. 回文链表
//const int a = 7;
//int A[a] = { 1,1,2,5,2,1,1 };
//ListNode *listA = new ListNode(A[0]);
//int i = 1;
//ListNode *addA = listA;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//std::cout << "<<< 9. 回文链表 >>>" << std::endl;
//while (listA != nullptr) {
// std::cout << listA->val << "->";
// listA = listA->next;
//}
//std::cout << "nullptr";
//Solution obj;
//bool check = obj.isPalindrome(listA);
//if (check)
// cout << " --> 该链表是回文";
//else
// cout << " --> 该链表不是回文";
10. 分隔链表
//const int a = 4;
//int A[a] = { 1,2,3,4 };
//ListNode *listA = new ListNode(A[0]);
//int i = 1;
//ListNode *addA = listA;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//Solution obj;
//vector<ListNode*> result = obj.splitListToParts(listA, 7);
//std::cout << "<<< 10. 分隔链表 >>>" << std::endl;
//std::cout << "[ ";
//for (int i = 0; i < result.size(); i++) {
// ListNode *res = result[i];
// std::cout << "[";
// if (res != nullptr) {
// while (res != nullptr && res->next != nullptr) {
// std::cout << res->val << ",";
// res = res->next;
// }
// std::cout << res->val;
// res = res->next;
// }
// else {
// std::cout << "nullptr";
// }
// if(i != result.size()-1)
// std::cout << "], ";
// else
// std::cout << "]";
//}
//std::cout << " ]";
11. 链表元素按奇偶聚集
//const int a = 8;
//int A[a] = { 1,2,3,4,5,6,7,8 };
//ListNode *listA = new ListNode(A[0]);
//int i = 1;
//ListNode *addA = listA;
//while (i < a) {
// ListNode *tmp = new ListNode(A[i]);
// addA->next = tmp;
// addA = addA->next;
// i++;
//}
//Solution obj;
//ListNode *result = obj.oddEvenList(listA);
//std::cout << "<<< 11. 链表元素按奇偶聚集 >>>" << std::endl;
//while (result != nullptr) {
// std::cout << result->val << "->";
// result = result->next;
//}
//std::cout << "nullptr" << std::endl;
return 0;
}