代码随想录算法训练营第四天 | 24.两两交换链表中的节点、 19.删除链表的倒数第N个节点 、07. 链表相交 、 142.环形链表II (cpp)

两两交换链表中的节点

题目链接

题目解答(增加了一些部分,方便编译器运行)

#include<iostream>

using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x): val(x), next(nullptr){}
};

class Solution {
public:
	static ListNode* swapPairs(ListNode* head) {
		if (head == nullptr || head->next == nullptr) return head;
		ListNode* Head = new ListNode(0);
		Head->next = head;
		ListNode* p1 = Head, *p2 = head, *p3 = head->next, *p4 = head->next->next;
		while (p2 != NULL && p3 != NULL) {
			p1->next = p3;
			p3->next = p2;
			p2->next = p4;

			if (!p2) break;
			else p1 = p2;
			if (!p1->next) break;
			else p2 = p1->next;
			if (!p2->next) break;
			else p3 = p2->next;
			p4 = p3->next;
		}
		head = Head->next;
		delete Head;
		return head;
		
	}
};

int main() {
	//输入
	int num;
	cin >> num;
	ListNode* head = new ListNode(num);
	ListNode* point = head;
	while (cin.get() != '\n') {
		cin >> num;
		point->next = new ListNode(num);
		point = point->next;
	}

	head = Solution::swapPairs(head);

	//输出
	while (head) {
		if (head->next == nullptr) {
			cout << head->val << " -> NULL";
		}
		else {
			cout << head->val << " -> ";
		}
		head = head->next;
	}
	return 0;
}

解题心得

1、处理两个节点,同样要拿到这两个节点的前后节点。

删除链表中的倒数第N个节点

题目解答(增加了一些部分,方便编译器运行)

#include<iostream>

using namespace std;

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x) : val(x), next(nullptr) {}
};

class Solution {
public:
	static ListNode* removeNthFromEnd(ListNode* head, int n) {
		ListNode* Head = new ListNode(0);
		Head->next = head;
		ListNode* point = head;
		int count = 0;
		while (count++ < n) {
			point = point->next;
			if (!point) break;
		}
		if (!point && count != n) return NULL;
		ListNode* point2 = Head;
		while (point) {
			point = point->next;
			point2 = point2->next;
		}
		ListNode* temp = point2->next;
		point2->next = temp->next;
		delete temp;
		head = Head->next;
		delete Head;
		return head;
	}
};

int main() {
	//输入
	int num;
	cin >> num;
	ListNode* head = new ListNode(num);
	ListNode* point = head;
	while (cin.get() != '\n') {
		cin >> num;
		point->next = new ListNode(num);
		point = point->next;
	}
	int n;
	cin >> n;

	head = Solution::removeNthFromEnd(head, n);
    
	//输出
	while (head) {
		if (head->next == nullptr) {
			cout << head->val << " -> NULL";
		}
		else {
			cout << head->val << " -> ";
		}
		head = head->next;
	}
	return 0;
}

解题心得

1、该题目运用双指针的快慢指针的方法,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。

链表相交

题目链接

题目解答

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* curA=headA;
        ListNode* curB=headB;
        int lenA=0, lenB=0;
        while(curA){
            curA=curA->next;
            lenA++;
        }
        while(curB){
            curB=curB->next;
            lenB++;
        }
        curA=headA, curB=headB;
        if(lenB > lenA){
            swap(lenA, lenB);
            swap(curA, curB);
        }
        int len=lenA-lenB;
        while(len-- && curA){
            curA=curA->next;
        }
        while(curA && curB){
            if(curA == curB) return curA;
            curA=curA->next;
            curB=curB->next;
        }
        return NULL;
    }
};

解题心得

该题目同样运用快慢指针的方法,先找出较长的链表,然后先让长链表的指针先跑一个差值,再让长链表的指针和断链表的从起始位置的指针同时跑,同时每跑一次比较两个结点是否一样,一样就返回该值;最后不一样就返回空。

环形链表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) {
        ListNode* fast=head, * slow=head;
        while(fast!=NULL && fast->next !=NULL){
            slow=slow->next;
            fast=fast->next->next;
            if(slow==fast){
                ListNode* node1=head;
                ListNode* node2=fast;
                while(node1 != node2){
                    node1=node1->next;
                    node2=node2->next;
                }
                return node1;
            }
        }
        return nullptr;
    }
};

解题心得

题目真的很难,感觉,还要运用到算法知识,所以,就直接看卡子哥的题解了。

该题目要判断链表是否环如果有环,而且如何找到这个环的入口。

1.如何判断是否有环,运用快慢指针,fast每次动两位,slow每次动一位,如果fast能追到slow(相对运动),那么一定会是有环的。

2.如何找到入口,定义两个指针,一个从链表的头结点出发,一个从快慢指针的相遇节点出发,让两个指针同时出发,两指针相遇的结点就是环的入口。

  • 7
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值