1. 单链表排序
方法一:使用辅助数组
使用辅助数组,时间复杂度O(nlogn),空间复杂度O(n)
class Solution {
public:
ListNode* sortInList(ListNode* head) {
ListNode* p = head;
vector<int> vec;
while(p != nullptr){
vec.push_back(p->val);
p = p->next;
}
sort(vec.begin(), vec.end());
p = head;
int i = 0;
while(p != nullptr){
p->val = vec[i++];
p = p->next;
}
return head;
}
};
方法二:双指针+归并排序
思路
- 以中点为分界,将链表拆分成两个子链表。
- 寻找链表的中点可以使用快慢指针的做法,快指针每次移动 2 步,慢指针每次移动 1步,当快指针到达链表末尾时,慢指针指向的链表节点即为链表的中点。对两个子链表分别排序。
- 将两个排序后的子链表合并,得到完整的排序后的链表。
上述过程可以通过递归实现。递归的终止条件是链表的节点个数小于或等于 1,即当链表为空或者链表只包含 1 个节点时,不需要对链表进行拆分和排序。
时间复杂度O(nlogn),空间复杂度O(1)
class Solution {
public:
ListNode* sortInList(ListNode* head) {
return mergeSort(head, nullptr);
}
private:
ListNode* mergeSort(ListNode* head, ListNode* tail){
if(head == nullptr) return head;
if(head->next == tail){
head->next = nullptr;
return head;
}
//主要就是要找到中间节点,用的是快慢指针法
ListNode* slow = head;
ListNode* fast = head;
//注意这里要判断的是!=tail,不要习惯性的写成nullptr
while(fast != tail && fast->next != tail){
slow = slow->next;
fast = fast->next->next;
}
return merge(mergeSort(head, slow), mergeSort(slow, tail));
}
ListNode* merge(ListNode* l1, ListNode* l2){
ListNode* head = new ListNode(0);
ListNode* cur = head;
while(l1 != nullptr && l2 != nullptr){
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 head->next;
}
};
2. 链表相加
思路:
- 因为两个链表都是正序存储数字的位数,所以需要将两个链表反转,这样两个链表中同一位置的数才可以相加
- 我们同时遍历两个链表,逐位计算它们的和,并与当前位置的进位值相加。使用头插法生成相加后的链表,这样生成的链表是正序的。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* addInList(ListNode* head1, ListNode* head2) {
// write code here
head1 = reverseList(head1);
head2 = reverseList(head2);
ListNode* head = new ListNode(1);
int pos = 0;
while (head1 != nullptr || head2 != nullptr) {
int val;
if (head1 && head2) val = head1->val + head2->val + pos;
else if (head1) val = head1->val + pos;
else val = head2->val + pos;
if (val >= 10) {
val = val- 10;
pos = 1;
} else {
pos = 0;
}
ListNode* node = new ListNode(val);
node->next = head->next;
head->next = node;
if(head1) head1 = head1->next;
if(head2) head2 = head2->next;
}
return pos ? head : head->next;
}
private:
ListNode* reverseList(ListNode* head) {
return reverseList(head, nullptr);
}
ListNode* reverseList(ListNode* head, ListNode* newHead) {
if (head == nullptr) return newHead;
ListNode* next = head->next;
head->next = newHead;
return reverseList(next, head);
}
};