链表中间节点---删除倒数第几个节点---相交链表---C++

#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <stack>
#include <unordered_set>

using namespace std;

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:
	//链表的中间节点
	ListNode* middleNode(ListNode* head) {//辅助数组
		vector<ListNode*> V = { head };
		while (V.back()->next != nullptr) {
			V.push_back(V.back()->next);
		}
		return V[V.size() / 2];
	}
	//链表的中间节点
	ListNode* middleNode1(ListNode* head) {//单指针
		int n = 0;
		ListNode* cur = head;
		while (cur != nullptr) {
			++n;
			cur = cur->next;
		}
		int j = 0;
		cur = head;
		while (j < n / 2) {
			++j;
			cur = cur->next;
		}
		return cur;
	}
	//链表的中间节点
	ListNode* middleNode2(ListNode* head) {//快慢指针法
		ListNode* slow = head;
		ListNode* fast = head;
		while (fast != NULL && fast->next != NULL) {
			slow = slow->next;
			fast = fast->next->next;
		}
		return slow;
	}

	int getLength(ListNode* head) {//计算链表长度
		int length = 0;
		while (head) {
			++length;
			head = head->next;
		}
		return length;
	}
	//删除链表的倒数第N个节点
	ListNode* removeNthfromEnd(ListNode* head, int n) {//计算链表长度
		ListNode* dummy = new ListNode(0, head);
		int length = getLength(head);
		ListNode* cur = dummy;
		for (int i = 1; i < length - n + 1; i++) {
			cur = cur->next;
		}
		cur->next = cur->next->next;
		ListNode* ans = dummy->next;
		delete dummy;
		return ans;
	}
	//删除链表的倒数第N个节点
	ListNode* removeNthfromEnd1(ListNode* head, int n) {//栈
		ListNode* dummy = new ListNode(0, head);
		stack<ListNode*> stk;//栈
		ListNode* cur = dummy;
		while (cur) {
			stk.push(cur);
			cur = cur->next;
		}

		for (int i = 0; i < n; i++) {
			stk.pop();
		}
		ListNode* pre = stk.top();
		pre->next = pre->next->next;
		ListNode* ans = dummy->next;
		delete dummy;
		return ans;
	}
	//删除链表的倒数第N个节点
	ListNode* removeNthfromEnd2(ListNode* head, int n) {//双指针法
		ListNode* dummy = new ListNode(0, head);
		ListNode* first = head;//双指针法
		ListNode* second = dummy;

		for (int i = 0; i < n; i++) {
			first->next;
		}

		while (first) {
			first = first->next;
			second = second->next;
		}
		second->next = second->next->next;
		ListNode* ans = dummy->next;
		delete dummy;
		return ans;
	}

	//相交链表
	ListNode* getIntersectionNode(ListNode* headA, ListNode* headB) {
		if (headA == nullptr || headB == nullptr) {
			return nullptr;
		}
		ListNode* pA = headA, * pB = headB;//双指针	O(m+n)	O(1)
		while (pA != pB) {
			pA = pA == nullptr ? headB : pA->next;
			pB = pB == nullptr ? headA : pB->next;
		}
		return pA;
	}

	//相交链表
	ListNode* getIntersectionNode1(ListNode* headA, ListNode* headB) {
		unordered_set<ListNode*> visited;//哈希集合	O(M+N)	O(M)
		ListNode* temp = headA;
		while (temp != nullptr) {
			visited.insert(temp);
			temp = temp->next;
		}
		temp = headB;
		while (temp != nullptr) {
			if (visited.count(temp)) {
				return temp;
			}
			temp = temp->next;
		}
		return nullptr;
	}
};

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值