链表操作
1,链表逆序-a leetcode 206
整个链表进行逆序
#include<stdio.h>
struct ListNode{
int val;
ListNode *next;
ListNode(int x):val(x),next(NULL){}
};
class Solution{
public:
ListNode* reverseList(ListNode*head){
ListNode *new_head=NULL;//指向新链表的头节点的指针
while(head){
ListNode *next=head->next;//备份head->next
head->next=new_head;//更新head->next
new_head=head; //移动new_head
head=next; //遍历节点
}
return new_head;//返回新链表头节点
}
}
int main(){
ListNode a(1);
ListNode b(2);
ListNode c(3);
ListNode d(4);
ListNode e(5);
a.next=&b;
b.next=&c;
c.next=&d;
d.next=&e;
Solution solve;
ListNode *head=&a;
printf("Before reverse:\n");
while(head){
printf("%d\n",head->val);
head=head->next;
}
head=slove.reverseList(&a);
printf("After reverse:\n");
while(head){
printf("%d\n",head->val);
head=head->next;
}
return 0;
}
2,链表逆序-b leetcode 92
已知头节点指针head,将链表从位置m到n逆序.(不申请额外空间)
class Solution{
public:
ListNode* reverseBetween(ListNode*head,int m,int n){
int change_len=n-m+1;//计算需要逆置节点的个数
ListNode * pre_head=NULL;//初始化开始逆置的节点的前驱
ListNode * result=head;//最终转换后的链表头节点,非特殊情况即为head
while(head&&--m){//将head向前移动m-1个位置
pre_head=head;//记录前驱节点
head=head->next;
}
ListNode *modify_list_tail=head;//将modify_list_tail指向当前的head,即逆置后的链表尾
ListNode *new_head=NULL;
while(head&&change_len){//逆置change_len个节点
ListNode *next =head->next;
head->next=new_head;
new_head=head;
head=next;
change_len--;
}
modify_list_tail->next=head;
if(pre_head){ //如果pre_head不为空说明不是第一个节点开始逆置的m>1
pre_head->next=new_head;//将逆置的链表的开始的节点前驱与逆置后的头节点连接
}
else{
result=new_head; //如果pre_head为空,说明m==1.从第一个节点开始逆置,结果即为逆置后的头节点
}
return result;
}
};
3,两个链表的交点 leetcode 160
#include <stdio.h>
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
int get_list_length(ListNode *head){
int len = 0;//遍历链表获取链表的长度
while(head){
len++;
head = head->next;
}
return len;
}
ListNode *forward_long_list(int long_len,
int short_len,
ListNode *head){
int delta = long_len - short_len;
while(head && delta){
head = head->next;
delta--;
}
return head;
}
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int list_A_len = get_list_length(headA);
int list_B_len = get_list_length(headB);
if (list_A_len > list_B_len){
headA = forward_long_list(list_A_len, list_B_len, headA);
}
else{
headB = forward_long_list(list_B_len, list_A_len, headB);
}
while(headA && headB){
if (headA == headB){
return headA;
}
headA = headA->next;
headB = headB->next;
}
return NULL;
}
};
4,两个链表是否有环 leetcode 141 142
快慢指针的思想,(环形赛道) 环的起始位置.
#include <stdio.h>
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;
ListNode *meet = NULL;
while(fast){
slow = slow->next;
fast = fast->next;
if (!fast){
return NULL;
}
fast = fast->next;
if (fast == slow){
meet = fast;
break;
}
}
if (meet == NULL){
return NULL;
}
while(head && meet){
if (head == meet){
return head;
}
head = head->next;
meet = meet->next;
}
return NULL;
}
};
5, 链表划分 leetcode 86
#include <stdio.h>
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
ListNode* partition(ListNode* head, int x) {
ListNode less_head(0);//创建临时节点 小于x
ListNode more_head(0);//创建临时节点 大于x
ListNode *less_ptr = &less_head;
ListNode *more_ptr = &more_head;
while(head){
if (head->val < x){
less_ptr->next = head;//建立连接
less_ptr = head;//节点后移
}
else {
more_ptr->next = head;
more_ptr = head;
}
head = head->next;//
}
less_ptr->next = more_head.next;//两个链表建立连接
more_ptr->next = NULL;//将more节点置空,即链表尾节点指向的指针置空
return less_head.next;//less_head.next即为链表新的头节点
}
};
int main(){
ListNode a(1);
ListNode b(4);
ListNode c(3);
ListNode d(2);
ListNode e(5);
ListNode f(2);
a.next = &b;
b.next = &c;
c.next = &d;
d.next = &e;
e.next = &f;
Solution solve;
ListNode *head = solve.partition(&a, 3);
while(head){
printf("%d\n", head->val);
head = head->next;
}
return 0;
}
6, 复杂链表的深度拷贝 leetcode 138
复杂链表的深度拷贝
#include <stdio.h>
#include <map>
#include <vector>
struct RandomListNode {
int label;
RandomListNode *next, *random;
RandomListNode(int x) : label(x), next(NULL), random(NULL) {}
};
class Solution {
public:
RandomListNode *copyRandomList(RandomListNode *head) {
std::map<RandomListNode *, int> node_map;//地址与节点 映射关系记录map
std::vector<RandomListNode *> node_vec;//使用vector根据存储节点位置访问地址
RandomListNode *ptr = head;
int i = 0;
while (ptr){
node_vec.push_back(new RandomListNode(ptr->label));
node_map[ptr] = i;
ptr = ptr->next;
i++;
}
node_vec.push_back(0);
ptr = head;
i = 0;
while(ptr){//再次遍历,连接新链表next,与random指针
node_vec[i]->next = node_vec[i+1];
if (ptr->random){
int id = node_map[ptr->random];
node_vec[i]->random = node_vec[id];
}
ptr = ptr->next;
i++;
}
return node_vec[0];
}
};
int main(){
RandomListNode a(1);
RandomListNode b(2);
RandomListNode c(3);
RandomListNode d(4);
RandomListNode e(5);
a.next = &b;
b.next = &c;
c.next = &d;
d.next = &e;
a.random = &c;
b.random = &d;
c.random = &c;
e.random = &d;
Solution solve;
RandomListNode *head = solve.copyRandomList(&a);
while(head){
printf("label = %d ", head->label);
if (head->random){
printf("rand = %d\n", head->random->label);
}
else{
printf("rand = NULL\n");
}
head = head->next;
}
return 0;
}