Tsai笔记:LeetCode笔记(1)—— 链表

Tsai笔记:LeetCode笔记(1)—— 链表

一、相关题型

二、 相关代码

#include <iostream>
#include <stack>
#include <vector>
using namespace std;


class ListNode {
public:
	int val;
	ListNode* next;
	ListNode(int v) : val(v), next(nullptr){}
};

class Solution {
public:
	//1. 找出两个链表的交点
	ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
		//1.若其中一个为nullptr说明没有交点
		if (headA == nullptr || headB == nullptr) {
			return nullptr;
		}
		//2.用两个指针将headA和headB遍历
		ListNode *List1 = headA, *List2 = headB;
		while (List1 != List2)
		{
			List1 = List1 != nullptr ? List1->next : headB;
			List2 = List2 != nullptr ? List2->next : headA;
		}
		return List1;
	}

	//2. 链表反转
	ListNode* reverseList(ListNode* head) {
		//1.若为nullptr或者next为nullptr直接返回head就行
		if (head == nullptr || head->next == nullptr) {
			return head;
		}

		//2.需要三个指针pre,curr,next
		ListNode *pre = nullptr, *curr = head, *next = nullptr;
		while (curr != nullptr) {
			next = curr->next;
			curr->next = pre;
			pre = curr;
			curr = next;
		}
		return pre;
	}

	//3. 归并两个有序的链表
	ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
		//1.若l1或l2为nullptr直接返回另一个
		if (l1 == nullptr)
			return l2;
		if (l2 == nullptr)
			return l1;

		//2.比较大小递归求解
		if (l1->val < l2->val)
		{
			l1->next = mergeTwoLists(l1->next, l2);
			return l1;
		}
		else {
			l2->next = mergeTwoLists(l1, l2->next);
			return l2;
		}
	}

	//4. 从有序链表中删除重复节点
	ListNode* deleteDuplicates(ListNode* head) {
		//1.若为nullptr或者next为nullptr直接返回head就行
		if (head == nullptr || head->next == nullptr)
			return head;

		//2.
		ListNode *tmp = head;
		while (tmp->next != nullptr) {
			if (tmp->val != tmp->next->val)
				tmp = tmp->next;
			else {
				ListNode *del = tmp->next;
				tmp->next = tmp->next->next;
				delete del;
			}
		}
		return head;
	}

	//5. 删除链表的倒数第 n 个节点
	ListNode* removeNthFromEnd(ListNode* head, int n) {
		ListNode *fast = head, *slow = head;

		while (n-- > 0)
			fast = fast->next;

		if (fast == nullptr)
			return head->next;

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

	}

	//6. 交换链表中的相邻结点
	ListNode* swapPairs(ListNode* head) {
		ListNode *pre = new ListNode(0);
		pre->next = head;
		head = pre;
		
		while (pre->next != nullptr && pre->next->next != nullptr) {
			ListNode *curr = pre->next, *next = pre->next->next;
			pre->next = next;
			curr->next = next->next;
			next->next = curr;
			pre = pre->next->next;
		}
		return head->next;
	}

	//7. 链表求和 I
	ListNode* addTwoNumbers_I(ListNode* l1, ListNode* l2) {
		int count = 0;
		ListNode *root = new ListNode(-1);
		ListNode *curr = root;
		while (l1 != nullptr || l2 != nullptr || count != 0) {
			int x = 0;
			if (l1 != nullptr) {
				x = l1->val;
				l1 = l1->next;
			}

			int y = 0;
			if (l2 != nullptr) {
				y = l2->val;
				l2 = l2->next;
			}

			int sum = x + y + count;
			ListNode *next = new ListNode(sum % 10);
			curr->next = next;
			curr = curr->next;
			count = sum / 10;
		}
		return root->next;
	}

	//8. 链表求和 II
	ListNode* addTwoNumbers_II(ListNode* l1, ListNode* l2) {
		//1.获取将两个链表压入两个栈中
		stack<int> stack1;
		while (l1 != nullptr) {
			stack1.push(l1->val);
			l1 = l1->next;
		}
		stack<int> stack2;
		while (l2 != nullptr) {
			stack2.push(l2->val);
			l2 = l2->next;
		}
		ListNode *next = new ListNode(-1);

		//2.取出栈中的元素相加作为新节点
		int count = 0;
		while (!stack1.empty() || !stack2.empty() || count != 0){
			int x = 0;
			if (!stack1.empty()) {
				x = stack1.top();
				stack1.pop();
			}
			int y = 0;
			if (!stack2.empty()) {
				y = stack2.top();
				stack2.pop();
			}

			int sum = x + y + count;
			ListNode *curr = new ListNode(sum % 10);
			curr->next = next->next;
			next->next = curr;
			count = sum / 10;
		}
		return next->next;
	}

	//9. 回文链表
	bool isPalindrome(ListNode* head) {
		//1.使用快慢指针找到链表的另一个开端
		ListNode *fast = head, *slow = head;
		while (fast) {//find mid node
			slow = slow->next;
			fast = fast->next ? fast->next->next : fast->next;
		}

		//2.翻转后部分的链表
		ListNode *prev = nullptr, *next;
		while (slow != nullptr) {
			next = slow->next;
			slow->next = prev;
			prev = slow;
			slow = next;
		}

		//3.比较两段是否相同
		while (prev != nullptr) {
			if (head->val != prev->val)
				return false;
			
			head = head->next;
			prev = prev->next;
		}
		return true;
	}

	//10. 分隔链表
	vector<ListNode*> splitListToParts(ListNode* root, int k) {
		//1.遍历链表得到其长度
		int Len = 0;
		ListNode *tmp = root;
		while (tmp != nullptr) {
			Len++;
			tmp = tmp->next;
		}

		//2.得到每个子链表平均元素的个数和余数,并将vector分为k份
		int avelen = Len / k;
		int Lev = Len % k;
		vector<ListNode *> result(k, nullptr);

		//3.对k段进行分配
		for (int i = 0; i < k; i++) {
			result[i] = root;
			int Childlen = Lev ? (avelen + 1) : avelen;
			for (int j = 0; j < Childlen - 1; j++) {
				root = root->next;
			}

			if (root) {
				ListNode *tmp = root->next;
				root->next = nullptr;
				root = tmp;
			}
			if (Lev) Lev--;
		}
		return result;
	}

	//11. 链表元素按奇偶聚集
	ListNode* oddEvenList(ListNode* head) {
		//1.若head为nullptr直接返回
		if (head == nullptr)
			return head;
		
		//2.三个指针odd、even、还有一个保存even的开始
		ListNode *odd = head, *even = head->next, *evenhead = head->next;
		while (even != nullptr && even->next != nullptr) {
			odd->next = odd->next->next;
			odd = odd->next;
			even->next = even->next->next;
			even = even->next;
		}
		odd->next = evenhead;
		return head;
	}
};


int main()
{	
	//2. 链表反转
	const int a = 6;
	int A[a] = { 2,2,4,4,6,7 };
	ListNode *listA = new ListNode(A[0]);
	ListNode *addA = listA;
	int i = 1;
	while (i < a) {
		ListNode *tmp = new ListNode(A[i]);
		addA->next = tmp;
		addA = addA->next;
		i++;
	}
	Solution obj;
	ListNode *res = obj.reverseList(listA);
	std::cout << "<<< 2. 链表反转 >>>" << std::endl;
	while (res != nullptr) {
		std::cout << res->val << "->";
		res = res->next;
	}
	std::cout << "nullptr" << std::endl;


	3. 归并两个有序的链表
	//const int a = 5, b = 6;
	//int A[a] = { 1,3,5,7,9 };
	//int B[b] = { 2,4,6,8,10,12 };
	//ListNode *listA = new ListNode(A[0]);
	//ListNode *listB = new ListNode(B[0]);
	//int i = 1;
	//ListNode *addA = listA, *addB = listB;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//i = 1;
	//while (i < b) {
	//	ListNode *tmp = new ListNode(B[i]);
	//	addB->next = tmp;
	//	addB = addB->next;
	//	i++;
	//}
	//Solution obj;
	//ListNode *result = obj.mergeTwoLists(listA, listB);
	//std::cout << "<<< 3. 归并两个有序的链表 >>>" << std::endl;
	//while (result != nullptr) {
	//	std::cout << result->val << "->";
	//	result = result->next;
	//}
	//std::cout << "nullptr" << std::endl;


	4. 从有序链表中删除重复节点
	//const int a = 6;
	//int A[a] = { 2,2,4,4,6,7 };
	//ListNode *listA = new ListNode(A[0]);
	//ListNode *addA = listA;
	//int i = 1;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//Solution obj;
	//ListNode *result = obj.deleteDuplicates(listA);
	//std::cout << "<<< 4. 从有序链表中删除重复节点 >>>" << std::endl;
	//while (result != nullptr) {
	//	std::cout << result->val << "->";
	//	result = result->next;
	//}
	//std::cout << "nullptr" << std::endl;


	5. 删除链表的倒数第 n 个节点
	//const int a = 6;
	//int A[a] = { 2,2,6,6,10,12 };
	//ListNode *listA = new ListNode(A[0]);
	//ListNode *addA = listA;
	//int i = 1;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//Solution obj;
	//ListNode *result = obj.removeNthFromEnd(listA, 3);
	//std::cout << "<<< 5. 删除链表的倒数第 n 个节点 >>>" << std::endl;
	//while (result != nullptr) {
	//	std::cout << result->val << "->";
	//	result = result->next;
	//}
	//std::cout << "nullptr" << std::endl;


	6. 交换链表中的相邻结点
	//const int a = 6;
	//int A[a] = { 2,3,4,5,6,7 };
	//ListNode *listA = new ListNode(A[0]);
	//ListNode *addA = listA;
	//int i = 1;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//Solution obj;
	//ListNode *result = obj.swapPairs(listA);
	//std::cout << "<<< 6. 交换链表中的相邻结点 >>>" << std::endl;
	//while (result != nullptr) {
	//	std::cout << result->val << "->";
	//	result = result->next;
	//}
	//std::cout << "nullptr" << std::endl;
	
	7. 链表求和 I
	//const int a = 3, b = 3;
	//int A[a] = { 2,4,3 };
	//int B[b] = { 5,6,4 };
	//ListNode *listA = new ListNode(A[0]);
	//ListNode *listB = new ListNode(B[0]);
	//int i = 1;
	//ListNode *addA = listA, *addB = listB;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//i = 1;
	//while (i < b) {
	//	ListNode *tmp = new ListNode(B[i]);
	//	addB->next = tmp;
	//	addB = addB->next;
	//	i++;
	//}
	//Solution obj;
	//ListNode *result = obj.addTwoNumbers_I(listA, listB);
	//std::cout << "<<< 7. 链表求和 I >>>" << std::endl;
	//while (result != nullptr) {
	//	std::cout << result->val << "->";
	//	result = result->next;
	//}
	//std::cout << "nullptr" << std::endl;
	

	8. 链表求和 II
	//const int a = 4, b = 3;
	//int A[a] = { 7,2,4,3 };
	//int B[b] = { 5,6,4 };
	//ListNode *listA = new ListNode(A[0]);
	//ListNode *listB = new ListNode(B[0]);
	//int i = 1;
	//ListNode *addA = listA, *addB = listB;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//i = 1;
	//while (i < b) {
	//	ListNode *tmp = new ListNode(B[i]);
	//	addB->next = tmp;
	//	addB = addB->next;
	//	i++;
	//}
	//Solution obj;
	//ListNode *result = obj.addTwoNumbers_II(listA, listB);
	//std::cout << "<<< 8. 链表求和 II >>>" << std::endl;
	//while (result != nullptr) {
	//	std::cout << result->val << "->";
	//	result = result->next;
	//}
	//std::cout << "nullptr" << std::endl;


	9. 回文链表
	//const int a = 7;
	//int A[a] = { 1,1,2,5,2,1,1 };
	//ListNode *listA = new ListNode(A[0]);
	//int i = 1;
	//ListNode *addA = listA;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//std::cout << "<<< 9. 回文链表 >>>" << std::endl;
	//while (listA != nullptr) {
	//	std::cout << listA->val << "->";
	//	listA = listA->next;
	//}
	//std::cout << "nullptr";
	//Solution obj;
	//bool check = obj.isPalindrome(listA);
	//if (check)
	//	cout << " --> 该链表是回文";
	//else
	//	cout << " --> 该链表不是回文";


	10. 分隔链表
	//const int a = 4;
	//int A[a] = { 1,2,3,4 };
	//ListNode *listA = new ListNode(A[0]);
	//int i = 1;
	//ListNode *addA = listA;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//Solution obj;
	//vector<ListNode*> result = obj.splitListToParts(listA, 7);
	//std::cout << "<<< 10. 分隔链表 >>>" << std::endl;
	//std::cout << "[ ";
	//for (int i = 0; i < result.size(); i++) {
	//	ListNode *res = result[i];
	//	std::cout << "[";
	//	if (res != nullptr) {
	//		while (res != nullptr && res->next != nullptr) {
	//			std::cout << res->val << ",";
	//			res = res->next;
	//		}
	//		std::cout << res->val;
	//		res = res->next;
	//	}
	//	else {
	//		std::cout << "nullptr";
	//	}
	//	if(i != result.size()-1)
	//		std::cout << "], ";
	//	else
	//		std::cout << "]";
	//}
	//std::cout << " ]";


	11. 链表元素按奇偶聚集
	//const int a = 8;
	//int A[a] = { 1,2,3,4,5,6,7,8 };
	//ListNode *listA = new ListNode(A[0]);
	//int i = 1;
	//ListNode *addA = listA;
	//while (i < a) {
	//	ListNode *tmp = new ListNode(A[i]);
	//	addA->next = tmp;
	//	addA = addA->next;
	//	i++;
	//}
	//Solution obj;
	//ListNode *result = obj.oddEvenList(listA);
	//std::cout << "<<< 11. 链表元素按奇偶聚集 >>>" << std::endl;
	//while (result != nullptr) {
	//	std::cout << result->val << "->";
	//	result = result->next;
	//}
	//std::cout << "nullptr" << std::endl;

	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值