class Solution {
public:
ListNode* reverseList(ListNode* head) {
ListNode* pre = head;
ListNode* cur = NULL;
while(pre != NULL){
ListNode* temp = pre->next; //暂存pre->next位置
pre->next = cur; //反转
cur = pre; //更新cur
pre = temp; //指向pre->next的位置
}
return cur;
}
};
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//递归
if(head == NULL || head->next == NULL){
return head;
}
ListNode* res = reverseList(head->next); // 反转链表的头结点
head->next->next = head;
head->next = NULL;
return res;
}
};
解法一:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
// head表示需要反转的头节点,pre表示需要反转头节点的前驱节点
ListNode* dummy = new ListNode(-1);
ListNode* pre = dummy;
dummy->next = head;
for(int i = 0;i < m-1; i++){
pre = pre->next;
}
ListNode* cur = pre->next;
for(int i = m; i < n; i++){
ListNode* t = cur->next;
cur->next = t->next;
t->next = pre->next;
pre->next = t;
}
return dummy->next;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
ListNode* res = new ListNode(0);
res->next = head;
ListNode* begin = res;
//m的前一个节点
for (int i = 1; i < m; i++){
begin = begin->next;
}
//begin->next是第m位节点,cur
ListNode *cur = begin->next;
ListNode *temp = NULL;
ListNode *pre = NULL;
//反转n-m次
for(int i = m; i <= n;i++){
temp = cur->next;
cur->next = pre;
pre = cur;
cur = temp;
}
//第m个节点指到第n+1个节点处
begin->next->next = temp;
//第m-1个节点指到第n个节点处
begin->next = pre;
return res->next;
}
};
题解:
设链表A的长度为a+c,链表B的长度为b+c,a为链表A不公共部分,b为链表B不公共部分,c为链表A、B的公共部分将两个链表连起来,A->B和B->A,长度:a+c+b+c=b+c+a+c,
若链表AB相交,则a+c+b与b+c+a就会抵消,它们就会在c处相遇;
若不相交,则c为nullptr,则a+b=b+a,它们各自移动到尾部循环结束,即返回nullptr
当ha或hb为空时,它们开始指向另一链表的头部,每次判断ha或hb是否为空进行赋值的好处是当链表AB没有公共部分时ha和hb同时为空,这样避免了死循环
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA==NULL || headB==NULL){
return 0;
}
ListNode* ha = headA;
ListNode* hb = headB;
while(ha != hb){
ha = ha ? ha->next : headB;
hb = hb ? hb->next : headA;
}
return ha;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head == NULL){
return head;
}
//新建一个空结点,用来指向头节点
ListNode* res = new ListNode(0);
res->next = head;
ListNode *left, *right, *cur = res; //cur当前做改变的节点
while(head != NULL && head->next != NULL){
left = head;
right = head->next;
//left ,right swap
cur->next = right;
left->next = right->next;
right->next = left;
//cur更新
cur = left;
// head更新
head = left->next;
}
return res->next;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
//快慢指针
bool hasCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
if(head == NULL){
return false;
}
while(fast != NULL && fast->next != NULL){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
//如果快慢指针相遇
return true;
}
}
return false;
}
};
思路:
快慢指针
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast != NULL && fast->next != NULL){
fast = fast->next->next;
slow = slow->next;
if(fast == slow){
break;
}
}
if(fast == NULL || fast->next == NULL){
return NULL;
}
//
fast = head;
int i = 0;
while(fast != slow){
fast = fast->next;
slow = slow->next;
i++;
}
return fast;
}
};
思路:
构造两个链表,最后拼接
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode* minList = new ListNode(0);
ListNode* maxList = new ListNode(0);
ListNode* minPointer = minList;
ListNode* maxPointer = maxList;
while(head != NULL){
if(head->val >= x){
maxPointer->next = head;
maxPointer = head;
}else{
minPointer->next = head;
minPointer = head;
}
head = head->next;
}
maxPointer->next = NULL;
minPointer->next = maxList->next;
return minList->next;
}
};
/*
// 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 ==NULL){
return head;
}
//遍历链表,建立映射关系
unordered_map<Node*, Node*> map;
Node* cur = head;
while(cur){
map[cur] = new Node(cur->val);
cur = cur->next;
}
// 遍历链表,根据map找新链表的random
cur = head;
while(cur){
map[cur]->next = map[cur->next]; //
map[cur]->random = map[cur->random]; //
cur = cur->next;
}
return map[head];
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
ListNode* newList = new ListNode(0);
ListNode* head = newList;
while(l2 && l1){
if(l1->val < l2->val){
head->next = l1;
l1 = l1->next;
}else{
head->next = l2;
l2 = l2->next;
}
head = head->next;
}
if(l2 == NULL){
head->next = l1;
}else{
head->next = l2;
}
return newList->next;
}
};
思路1:优先队列介绍
https://blog.csdn.net/weixin_36888577/article/details/79937886
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* mergeKLists(vector<ListNode*>& lists) {
priority_queue<pair<int, ListNode*>, vector<pair<int, ListNode*>>, greater<pair<int, ListNode*>>> m;
// 定义:priority_queue
for(auto x : lists){
if(x){
m.push(make_pair(x->val,x));
}
}
ListNode* root = new ListNode(-1);
auto q = root;
while(!m.empty()){
auto cur = m.top();
m.pop();
q->next = cur.second;
q = q->next;
if(cur.second->next){
m.push(make_pair(cur.second->next->val, cur.second->next));
}
}
return root->next;
}
};
思路2:分而治之
class Solution {
public:
// 合并两个有序链表(递归)
ListNode* merge(ListNode* p1, ListNode* p2){
if(!p1)
return p2;
if(!p2)
return p1;
if(p1->val <= p2->val){
p1->next = merge(p1->next, p2);
return p1;
}else{
p2->next = merge(p1, p2->next);
return p2;
}
}
ListNode* merge(vector<ListNode*>& lists, int start, int end){
if(start == end)
return lists[start];
int mid = (start + end) / 2;
ListNode* l1 = merge(lists, start, mid);
ListNode* l2 = merge(lists, mid+1, end);
return merge(l1, l2);
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
if(lists.size() == 0)
return NULL;
return merge(lists, 0, lists.size()-1);
}
};
思路1: 快慢指针 反转链表 比较
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
// 题解:快慢指针法,快指针走两步,慢指针走一步,找到链表的中点。然后,翻转后半部分。最后从头、中点开始判断是否相同。
bool isPalindrome(ListNode* head) {
if(head==NULL || head->next==NULL){
return true;
}
ListNode* fast = head;
ListNode* slow = head;
ListNode* pre = NULL;
//找中点
while(fast && fast->next){
slow = slow->next;
fast = fast->next->next;
}
// slow之后断开,反转,反转完后,pre指向反转链表的头结点
while(slow){
ListNode* temp = slow->next;
slow->next = pre;
pre = slow;
slow = temp;
}
// 比较链表,若为奇数,后半部分比前半部分多1各节点
while(head && pre){
if(head->val != pre->val){
return false;
}
head = head->next;
pre = pre->next;
}
return true;
}
};
思路2: 栈
class Solution {
public:
bool isPalindrome(ListNode* head) {
stack<int> s;
ListNode* p = head;
// 入栈
while(p){
s.push(p->val);
p = p->next;
}
p = head;
while(p){
if(p->val != s.top()){
return false;
}
p = p->next;
s.pop();
}
return true;
}
};
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseKGroup(ListNode* head, int k) {
ListNode* dummy = new ListNode(0);
dummy->next = head;
ListNode* pre = dummy; //初始化
ListNode* end = dummy;
while(end->next != NULL){
//找到end,走k步
for(int i = 0; i < k && end != NULL; i++){
end = end->next;
}
// 跳出循环,到结尾
if(end == NULL){
break;
}
// 初始化 指针顺序:pre,start,end,next
ListNode* start = pre->next;
ListNode* next = end->next;
// 断开end
end->next = NULL;
// 反转start-end之间的节点
pre->next = reverse(start);
// start连接上原来的链表
start->next = next;
// 更新pre
pre = start;
// 更新end
end = pre;
}
return dummy->next;
}
ListNode* reverse(ListNode* head){
ListNode* pre = NULL;
ListNode* cur = head;
while(cur != NULL){
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
};
思路:
由于对时间和空间复杂度有要求,所以只能用归并排序了