链表总结

文章目录

  • 链表反转
    • 反转 *m* 到 *n* 的链表
    • k个一组翻转链表
  • 两两交换链表中的节点
  • 合并K个升序链表
  • 删除排序链表中的重复元素
  • 分隔链表
  • 重排链表
  • [环形链表 II](https://leetcode-cn.com/problems/linked-list-cycle-ii/)
  • 回文链表
  • 复制带随机指针的链表
  • 有序链表转换二叉搜索树

链表反转

ListNode* reverse(ListNode *a)
{
    ListNode *pre=NULL;
    ListNode *cur=a;
    ListNode *nex;
    while(cur)
    {
        nex=cur->next;
        cur->next=pre;
        pre=cur;
        cur=nex;
    }

    return pre;
}

反转 mn 的链表

/**
 * 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) {
        if(head==NULL || head->next==NULL)
            return head;
        ListNode *node=head;
        int i=1;
        ListNode *pre=NULL;
        ListNode *nex;
        while(inext;
            i++;
        }

        ListNode *t1=pre;
        ListNode *t2=node;
        while(i<=n && node)
        {
            nex=node->next;
            node->next=pre;
            pre=node;
            node=nex;
            i++;
        }
        if(m==1)
        {
            t2->next=node;
            return pre;
        }

        t1->next=pre;
        t2->next=node;

        return head;
   
    }
};

k个一组翻转链表

/**
 * 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) {
        if(head==NULL)
        {
            return NULL;
        }

        ListNode *a,*b;
        a=b=head;
        for(int i=0;inext;
        }

        ListNode *newHead=reverse(a,b);
        a->next=reverseKGroup(b,k);

        return newHead;
  
    }

    //左闭右开
    ListNode* reverse(ListNode *a,ListNode *b)
    {
        ListNode *pre=NULL;
        ListNode *cur=a;
        ListNode *nex;
        while(cur!=b)
        {
            nex=cur->next;
            cur->next=pre;
            pre=cur;
            cur=nex;
        }

        return pre;
    }
};

两两交换链表中的节点

/**
 * 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 NULL;
        ListNode *a=head,*b=head;
        for(int i=0;i<2;i++)
        {
            if(b==NULL)
                return head;
            b=b->next;
        }

        ListNode *newHead=reverse(a,b);
        a->next=swapPairs(b);

        return newHead;

        
    }

    ListNode *reverse(ListNode *a,ListNode *b)
    {
        ListNode *pre=NULL;
        ListNode *cur=a;
        ListNode *nex;
        while(cur!=b)
        {
            nex=cur->next;
            cur->next=pre;
            pre=cur;
            cur=nex;
        }

        return pre;
    }
};

迭代

/**
 * 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 || head->next==NULL)
            return head;
        ListNode* res=new ListNode(-1);
        res->next=head;
        ListNode* pre=res;
        ListNode* cur=head;
        ListNode* nex=head->next;
        while(nex)
        {
            cur->next=nex->next;
            nex->next=cur;
            pre->next=nex;

            pre=cur;
            if(cur->next)
            {
                cur=cur->next;
                nex=cur->next;
            
            }
            else
                break;

        }

        return res->next;
        
    }
};

递归

/**
 * 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 || head->next==NULL)
            return head;
        
        ListNode* first=head;
        ListNode* second=head->next;

        first->next=swapPairs(second->next);
        second->next=first;

        return second;   
    }
};

合并K个升序链表

  • make_heap

  • push_back,push_heap

  • pop_heap,pop_back()

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
    inline bool cmp(ListNode* v1,ListNode* v2)
    {
        return v1->val > v2->val;//greator()
    }
class Solution {
public:

    ListNode* mergeKLists(vector& lists) {
        vectormin;
        for(auto m:lists)
        {
            if(m)
                min.push_back(m);
        }
        ListNode* res=new ListNode(-1);
        ListNode* node=res;
        make_heap(min.begin(),min.end(),cmp);
        while(!min.empty())
        {
            ListNode* temp=min.front();
            pop_heap(min.begin(),min.end(),cmp);//pop_heap后,最小元素被放置在底部容器的最尾端,需要pop_back()取走
            min.pop_back();
            node->next=temp;
            node=node->next;
            if(temp->next)//通不过,可能遇到空链表,即lists链表有可能为空
            {
                min.push_back(temp->next);
                push_heap(min.begin(),min.end(),cmp);
            }

        }

        return res->next;
        
    }
};

priority_queue

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
    inline bool cmp(ListNode* v1,ListNode* v2)
    {
        return v1->val > v2->val;
    }
class Solution {
public:

    ListNode* mergeKLists(vector& lists) {
        priority_queue,decltype(cmp)* >min(cmp);
        for(auto m:lists)
        {
            if(m)
                min.push(m);
        }
        ListNode* res=new ListNode(-1);
        ListNode* node=res;

        while(!min.empty())
        {
            ListNode* temp=min.top();
            min.pop();
            node->next=temp;
            node=node->next;
            if(temp->next)//通不过,可能遇到空链表,即lists链表有可能为空
            {
                min.push(temp->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:
    ListNode* deleteDuplicates(ListNode* head) {
        if(head==NULL || head->next==NULL )
        {
            return head;
        }
        ListNode *node=head;
        ListNode *nex=head->next;
        while(nex)
        {
            if(nex->val==node->val)
            {
                node->next=nex->next;
                nex=nex->next;
            }
            else
            {
                node=nex;
                nex=nex->next;
            }   
        }
        /*
            if(nex->val==node->val)
            {
                nex=nex->next;
            }
            else
            {
                node->next=nex;
                node=node->next;
                nex=nex->next;
            }
            */
        //node->next=NULL;
        return head;
    }
};

给定一个排序链表,删除所有含有重复数字的节点,只保留原始链表中 没有重复出现 的数字。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* deleteDuplicates(ListNode* head) {
        ListNode *res=new ListNode(-1);
        res->next=head;
        ListNode *cur= res;

        ListNode *left;
        ListNode *right;
        while(cur->next)
        {
            left=cur->next;
            right=left;
            //直到left->val!=right->next->val
            while(right->next && left->val==right->next->val)
            {
                right=right->next;
            }
            if(left==right)//没有移动right,后一个元素和left不相等
            {
                cur=cur->next;
            }
            else
            {
                cur->next=right->next;
            }

        }

        return res->next;   
    }
};

分隔链表

给定一个链表和一个特定值 x,对链表进行分隔,使得所有小于 x 的节点都在大于或等于 x 的节点之前。

你应当保留两个分区中每个节点的初始相对位置。

#include
using namespace std;
 
struct ListNode {
    int val;
    ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};

class Solution {
public:
    ListNode* partition(ListNode* head, int x) {
        while(head==NULL || head->next==NULL)
            return head;
        ListNode *first=new ListNode(-1);
        ListNode *second= new ListNode(-1);
        ListNode *cur=head;
        ListNode *p1=first;
        ListNode *p2=second;
        while(cur)
        {
            if(cur->val < x)
            {
                first->next=cur;
                first=first->next;
                cur=cur->next;
            }
            else
            {
                second->next=cur;
                second=second->next;
                cur=cur->next;
            }
        }
        second->next=NULL;//必须加上此句,因为second的尾节点不一定是链表的输入尾节点
        first->next=p2->next;
        return p1->next;
        
    }
};

int main(){
    
	ListNode * preHead=new ListNode(-1);
	int n,val,x;
	cin>>n>>x;
	ListNode * node=preHead;
	while(n--)
	{
		cin>>val;
	    node->next	= new ListNode(val);
	    node=node->next;
	}
	
	Solution s;
	ListNode* res ;
	res= s.partition(preHead->next,x);
	while(res)
	{
		cout<val<<" ";
		res=res->next;
	}
	
	return 0;
	
}

重排链表

给定一个单链表 L:L0→L1→…→Ln-1→Ln ,
将其重新排列后变为: L0→Ln→L1→Ln-1→L2→Ln-2→…

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
bool isOddNumbder=false;
    void reorderList(ListNode* head) {
        if(!head || !head->next)
            return;
		ListNode* mid = getMidNode(head);//奇数个数找到中间节点,偶数个数会找到中偏左节点
		ListNode* rearPartReverseList = reverse(mid->next);//奇数个数,后半部分少一个节点,偶数个数相等 
        ListNode *temp=new ListNode(-1);
        ListNode*head1=head;
        ListNode*head2=rearPartReverseList;
        while(head2) 
        {
        	temp->next=head1;
        	head1=head1->next;
        	temp=temp->next;
        	temp->next=head2;
        	head2=head2->next;
        	temp=temp->next;
		}
		if(isOddNumbder)
		{
		    temp->next=head1;
		    temp=temp->next;
		    temp->next=NULL;
				
		}
		head=temp->next;   
		return ;

	}

	ListNode* getMidNode(ListNode* head)
	{
		ListNode *fast = head;
		ListNode *slow = head;
		while (fast->next && fast->next->next)
		{
			fast = fast->next->next;
			slow = slow->next;
			if(fast)
			    isOddNumbder=true;
		}
		return slow;
	}

	ListNode* reverse(ListNode* head)
	{
		ListNode* reverseListNode = NULL;
		ListNode* pre = NULL;
		ListNode* cur = head;
		ListNode* nex = NULL;
		while (cur)
		{
			nex = cur->next;
			if (nex == NULL)
			{
				reverseListNode = cur;
			}
			cur->next = pre;//这里 cur->next变了 
			pre = cur;
			cur = nex;//不能用cur=cur->next 
		}

		return reverseListNode;
	}
};

环形链表 II

/**
 * 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) {
        if(head==NULL || head->next==NULL || head->next->next==NULL)
            return NULL;
        ListNode* fast=head;
        ListNode* slow=head;
        while(fast && fast->next )
        {
            fast=fast->next->next;
            slow=slow->next;
            if(fast==slow)
                break;
        }
        
        if(fast!=slow)
            return NULL;

        slow=head;
        while(slow!=fast)
        {
            slow=slow->next;
            fast=fast->next;
        }

        return slow;
        
    }
};

回文链表

/**
 * 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,*slow=head;
        ListNode *pre=NULL,  *cur=NULL;
        while(fast && fast->next)
        {
            cur=slow;
            slow=slow->next;//保存后节点
            fast=fast->next->next;
            cur->next=pre;
            pre=cur;
        }

        //奇数节点fast->next为NULL,跳过中间节点,偶数节点不需要
        //1->2->3->4->5  p指向2,slow指向3
        //1->2->3->4     p指向2,slow指向3
        //需要将链表前半部分翻转
        if(fast)
            slow=slow->next;
        while(slow)
        {
            if(slow->val!=cur->val)
                return false;
            slow=slow->next;
            cur=cur->next;
        }

        return true;
    }
};

复制带随机指针的链表

/*
// 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)
            return NULL;
        Node * cur=head;
        //1.给原来的链表的每个结点复制一个新节点并且插入到对应的后面
        while(cur)
        {
            Node *temp=new Node(cur->val);
            temp->next=cur->next;
            cur->next=temp;
            cur=cur->next->next;
        }
        //2.把复制的结点的random指针指向被复制结点的random指针的下一个结点
        cur=head;
        while(cur){
            Node *temp=cur->next;
            if(cur->random)
            {
                temp->random=cur->random->next;
            }
            cur=cur->next->next;
        }
        //3.拆分新/老链表
        cur=head;
        Node *copy=head->next;
        Node *newHead=head->next;
        while(copy->next)
        {
            cur->next=copy->next;
            copy->next=cur->next->next;
            cur=cur->next;
            copy=copy->next;
        }
        cur->next=NULL;

        return newHead;
    }
};

有序链表转换二叉搜索树

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode* sortedListToBST(ListNode* head) {
        vectornums;
        while(head)
        {
            nums.push_back(head->val);
            head=head->next;   
        }

        TreeNode *res=binarySearch(nums,0,nums.size()-1);
        return res;
    }

    TreeNode* binarySearch(vector& nums,int start, int end)
    {
        if(start>end)
            return NULL;
        int mid=(start+end)/2;
        TreeNode *root=new TreeNode(nums[mid]);
        root->left=binarySearch(nums,start,mid-1);
        root->right=binarySearch(nums,mid+1,end);
        return root;
    }
};

你可能感兴趣的:(链表总结)