• 链表LeetCode练习


    链表LeetCode练习

    反转链表

    class Solution {
    public:
    	ListNode* reverseList(ListNode* head)
    	{
    		if (head == NULL || head->next == NULL) return head;
    		ListNode* t1, *t2,*t;
    		t1 = head;
    		t2 = head->next;
    		t1->next = NULL;
    		while (t2)
    		{
    			t = t2->next;
    			t2->next = t1;
    			t1 = t2;
    			t2 = t;
    		}
    		return t1;
    	}
    };
    
    

    两两交换链表中的节点

    class Solution {
    public:
        ListNode* swapPairs(ListNode* head) {
            ListNode **pp = &head, *a, *b;
            while ( (a = *pp) && (b = a->next)){
                a->next = b->next;
                b->next = a;
                *pp = b;
                pp = &(a->next);
            }
            return head;
    
        }
    };
    

    环形链表

    class Solution {
    public:
        bool hasCycle(ListNode *head) {
            //特判链表结点为空的情况
            if(!head) return false;
            ListNode* slow = head;
            ListNode* fast = head;
            while(fast->next && fast->next->next) {
                //必须让快指针先跑
                fast = fast->next->next;
                if(slow == fast) return true;
                else slow = slow->next;
            }
            return false;
        }
    };
    

    环形链表 II

    class Solution {
    public:
        ListNode* detectCycle(ListNode* head) {
    	ListNode* fastPtr=head, *slowPtr=head;
    	// 让fast与slow指针第一次相遇
    	while (fastPtr!=NULL && fastPtr->next!=NULL)
    	{
    		fastPtr = fastPtr->next->next;
    		slowPtr = slowPtr->next;
    		if (fastPtr==slowPtr)
    		{
    			// 从相遇点再走“非环部分长度”一定可以再次走到环起点
    			fastPtr = head;
    			while (fastPtr != slowPtr)
    			{
    				fastPtr = fastPtr->next;
    				slowPtr = slowPtr->next;
    			}
    			return fastPtr;
    			break;
    		}
    	}
    
    	return nullptr;
    }
    };
    
    

    K 个一组翻转链表

    class Solution {
    public:
        ListNode* reverseKGroup(ListNode* head, int k) {
            //特殊情况:NULL或仅有一个节点
            if(head == nullptr || head->next == nullptr)
                return head;
    
            //虚拟头结点
            ListNode *dummyHead = new ListNode(0);
            dummyHead->next = head;
    
            //next指向当前结点的下一个结点
            ListNode *next = head;
            //pre_tail指向上一段链表的尾节点,初始值为空指针
            ListNode *pre_tail = nullptr;
            //每一个段的头结点
            ListNode *newHead = head;
            //计数值,当count增加到k时,就断链,倒置,挂链
            int count = 0;
    
            while(head){
                count++;
                next = head->next;
                if(count == k){
                    //断链,并且将该小段链表送入倒置函数中
                    head->next = nullptr;
                    HeadTail headTail = reverse(newHead);
    
                    //挂链:处理倒置后的链表的头和尾,巧妙利用pre初始值是否为空
                    if(pre_tail)
                        //不为空,则上一段链表尾节点指向新置链表头结点
                        pre_tail->next = headTail.head;
                    else
                        //为空,则虚拟头结点指向新置链表头结点
                        dummyHead->next = headTail.head;
    
                    headTail.tail->next = next;
    
                    //更新上一段链表的尾节点、下一段链表的头结点和计数值count
                    pre_tail = headTail.tail;
                    newHead = next;
                    count = 0;//别忘记计数值重置
                }
                
                head = next;
            }
            return dummyHead->next;//dummyHead大法好
        }
    
        //链表的头和尾结构体
        struct HeadTail{
            ListNode *head;
            ListNode *tail;
        };
    
        //reverse函数返回两个参数:倒置后的链表头和尾
        HeadTail reverse(ListNode* head){
            //巧妙使用pre指针,初始值为空
            ListNode *pre = nullptr;
            ListNode *cur = head;
            ListNode *next = head;
            while(cur){
                next = cur->next;
                //pre初始值为空
                cur->next = pre;
                //更新pre值,很巧妙
                pre = cur;
                cur = next;
            }
            HeadTail headTail;
            headTail.head = pre;
            headTail.tail = head;
    
            return headTail;
        }
    };
    
  • 相关阅读:
    雅虎公司C#笔试题
    DES
    从Socket看Visual C#.Net网络程序开发
    进一步接触C#委托与事件
    学习C#消息:循序渐进
    解惑答疑:C#委托和事件
    利用Visual C#实现Windows管道技术1
    使用命名管道通过网络在进程之间进行通信
    C#体验编程技术 类与对象
    学习C#实现HTTP协议:多线程文件传输
  • 原文地址:https://www.cnblogs.com/liugangjiayou/p/12389549.html
Copyright © 2020-2023  润新知