关于常见的各种链表算法题C++代码实现(希望可以持续更新…)

1、定义单链表/双链表

struct ListNode {
	int val;
	ListNode* next;
	ListNode(int x) :val(x),next(NULL) {}
};
struct ListNode{
	ListNode* pre;
	ListNode* next;
	int value;
	ListNode(int _key, int _value):
		pre(nullptr),
		next(nullptr),
		value(_value)
	{}
};

2、单链表的反转

NC78 反转链表

属于是必知必会题了~

ListNode* ReverseList(ListNode* pHead) {
	ListNode* pre = nullptr;
	ListNode* cur = pHead;
	ListNode* nex = nullptr;
	while (cur) {
		nex = cur->next;
		cur->next = pre;
		pre = cur;
		cur = nex;
	}
	return pre;
}

3、判断链表中是否有环

NC4 判断链表中是否有环

经典之快慢指针

bool hasCycle(ListNode *head) {
    if(head == nullptr){
        return false;
    }
    ListNode* fast = head;
    ListNode* slow = head;
    while(fast != nullptr && fast->next != nullptr){
        fast = fast->next->next;
        slow = slow->next;
        if(fast == slow){
            return true;
       }
    }
    return false;
}

4、链表中环的入口结点

NC3 链表中环的入口结点

借助一下set

ListNode* EntryNodeOfLoop(ListNode* pHead) {
	set<ListNode*> s ;
	while (pHead != nullptr) {
		if (!s.empty()) {
			set<ListNode*>::iterator it = s.begin();
			it = s.find(pHead);
			if (it != s.end()) {
				return pHead;
			}
		}
		s.insert(pHead);
		pHead = pHead->next;
	}
	return  pHead;
}

5、两个链表的第一个公共结点

NC66 两个链表的第一个公共结点

ListNode* FindFirstCommonNode( ListNode* pHead1, ListNode* pHead2) {
     ListNode *ta = pHead1, *tb = pHead2;
     while (ta != tb) {
       ta = ta ? ta->next : pHead2;
       tb = tb ? tb->next : pHead1;
    }
    return ta;
}

6、合并两个排序的链表

NC33 合并两个排序的链表

ListNode* Merge(ListNode* pHead1, ListNode* pHead2) {
	if (pHead1 == nullptr && pHead2 == nullptr) {
		return pHead1;
	}
	else if (pHead2 == nullptr && pHead1 != nullptr) {
		return pHead1;
	}
	else if (pHead1 == nullptr && pHead2 != nullptr) {
		return pHead2;
	}

	ListNode* pre = pHead1;
	vector<int> v;
	while (pre != nullptr) {
		v.push_back(pre->val);
		pre = pre->next;
	}
	pre = pHead2;
	while (pre != nullptr) {
		v.push_back(pre->val);
		pre = pre->next;
	}

	sort(v.begin(), v.end());

	ListNode* head;
	head = new ListNode(v[0]);
	ListNode* p = nullptr;
	head->next = p;
	ListNode* cur = head;
	for (size_t i = 1; i < v.size(); ++i) {
		p = new ListNode(v[i]);
		cur->next = p;
		cur = cur->next;
	}
	return head;
}

7、 合并k个已排序的链表

NC51 合并k个已排序的链表

ListNode* mergeKLists(vector<ListNode*>& lists) {
	if (lists.empty()) {
		return nullptr;
	}
	vector<int> cur;
	for (size_t i = 0; i < lists.size(); ++i) {
		ListNode* head = lists[i];
		while (head) {
			cur.push_back(head->val);
			head = head->next;
		}
	}
	sort(cur.begin(), cur.end());
	ListNode* ret = new ListNode(0);
	ListNode* pre = ret;
	for (size_t i = 0; i < cur.size(); ++i) {
		pre->next = new ListNode(cur[i]);
		pre = pre->next;
	}
	return ret->next;
}

8、单链表的排序

NC70 单链表的排序

ListNode* sortInList(ListNode* head) {
	if (head == nullptr) {
		return  nullptr;
	}
	vector<int> v;
	ListNode* next = head->next;
	while (head != nullptr) {
		v.push_back(head->val);
		head = next;
		if (next != nullptr) {
			next = head->next;
		}
		else {
			next = nullptr;
		}
	}
	sort(v.begin(), v.end());
	ListNode* pHead = new ListNode(v[0]);
	pHead->next = nullptr;
	ListNode* cur = pHead;
	for (size_t i = 1; i < v.size(); ++i) {
		ListNode* pre = new ListNode(v[i]);
		pre->next = nullptr;
		cur->next = pre;
		cur = cur->next;
	}
	return pHead;
}

9、链表中的节点每k个一组翻转

NC50 链表中的节点每k个一组翻转

ListNode* reverseKGroup(ListNode* head, int k) {
	if (head == nullptr) {
		return nullptr;
	}
	else if (k == 0) {
		return head;
	}
	ListNode* ret = new ListNode(0);
	stack<int> s;
	int num = 0;
	ListNode* cur = head;
	ListNode* pre = ret;

	while (cur) {
		while (num < k && cur != nullptr) {
			s.push(cur->val);
			cur = cur->next;
			num++;
		}
		if (s.size() == k) {
			while (!s.empty()) {
				pre->next = new ListNode(s.top());
				s.pop();
				pre = pre->next;
			}
		}
		else {
			stack<int> cur_s;
			while (!s.empty()) {
				cur_s.push(s.top());
				s.pop();
			}
			while (!cur_s.empty()) {
				pre->next = new ListNode(cur_s.top());
				cur_s.pop();
				pre = pre->next;
			}
		}
		num = 0;
	}
	return ret->next;
}

10、两个链表生成相加链表

NC40 两个链表生成相加链表

ListNode* addInList(ListNode* head1, ListNode* head2) {
	if (head1 == nullptr && head2 != nullptr) {
		return head2;
	}
	else if ((head1 != nullptr && head2 == nullptr) || (head1 == nullptr && head2 == nullptr)) {
		return head1;
	}
	stack<int> s1;
	stack<int> s2;

	while (head1 != nullptr) {
		s1.push(head1->val);
		head1 = head1->next;
	}
	while (head2 != nullptr) {
		s2.push(head2->val);
		head2 = head2->next;
	}

	stack<int> ret_s;
	int num = max(s1.size(), s2.size());

	int cur = 0;  //标记是否需要进位
	int ret = 0;
	for (int i = 0; i < num; ++i) {
		if (s1.empty()) {
			s1.push(0);
		}
		else if (s2.empty()) {
			s2.push(0);
		}
		ret = s1.top() + s2.top();
		//判断是否需要进位
		if (cur == 1) {
			ret += 1;
			cur = 0;
		}
		//判断下次是否需要进位
		if (ret >= 10) {
			cur = 1;
			ret_s.push(ret % 10);
		}
		else {
			ret_s.push(ret);
		}
		s1.pop();
		s2.pop();
	}
	if (cur == 1) {
		ret_s.push(1);
	}

	ListNode* pHead = new ListNode(ret_s.top());
	ListNode* pCur = nullptr;
	pCur = pHead;
	pHead->next = nullptr;
	ret_s.pop();
	size_t size = ret_s.size();
	for (size_t i = 0; i < size; ++i) {
		ListNode* node = new ListNode(ret_s.top());
		pCur->next = node;
		pCur = node;
		ret_s.pop();
	}
	return pHead;
}

11、删除有序链表中重复的元素-I

NC25 删除有序链表中重复的元素-I

去重!

ListNode* deleteDuplicates(ListNode* head) {
	if (head == nullptr) {
		return  nullptr;
	}
	set<int> s;
	ListNode* ret = new ListNode(0);
	ListNode* cur = head;
	ListNode* pre = ret;
	while (cur) {
		s.insert(cur->val);
		cur = cur->next;
	}

	for (set<int>::iterator it = s.begin(); it != s.end(); ++it) {
		pre->next = new ListNode(*it);
		pre = pre->next;
	}
	return ret->next;
}

12、删除有序链表中重复的元素-II

NC24 删除有序链表中重复的元素-II

有重复就删除!

ListNode* deleteDuplicates2(ListNode* head) {
	if (head == nullptr) {
		return  nullptr;
	}

	ListNode* ret = new ListNode(0);
	ListNode* pre = ret;
	ListNode* cur = head;
	map<int, int> m;
	while (cur) {
		map<int, int>::iterator it = m.find(cur->val);
		if (it != m.end()) {
			it->second += 1;
		}
		else {
			m.insert(make_pair(cur->val, 1));
		}
		cur = cur->next;
	}
	
	for (map<int, int>::iterator it = m.begin(); it != m.end(); ++it) {
		if (it->second == 1) {
			ListNode* nex = new ListNode(it->first);
			pre->next = nex;
			pre = pre->next;
		}
	}
	return ret->next;
}

13、链表内指定区间反转

NC21 链表内指定区间反转

ListNode* reverseBetween(ListNode* head, int m, int n) {
	if (head == nullptr || m == n) {
		return head;
	}

	ListNode* ret = new ListNode(0);
	ListNode* cur = ret;

	vector<int> v;
	stack<int> s;

	int num = 1;
	while (head != nullptr) {
		if (num < m) {
			v.push_back(head->val);
		}
		else if (num >= m && num <= n) {
			s.push(head->val);
		}
		else {
			while (!s.empty()) {
				v.push_back(s.top());
				s.pop();
			}
			v.push_back(head->val);
		}
		head = head->next;
		num++;
	}
	if (!s.empty()) {
		while (!s.empty()) {
			v.push_back(s.top());
			s.pop();
		}
	}
	for (size_t i = 0; i < v.size(); ++i) {
		ListNode* pre = new ListNode(v[i]);
		cur->next = pre;
		cur = cur->next;
	}
	return ret->next;
}

14、 排序奇升偶降链表

NC207 排序奇升偶降链表
面试题,要求只能通过链表操作来完成!!!(不然可以放到数组里sort)

ListNode* sortLinkedList(ListNode* head) {
	if (head == nullptr) {
		return nullptr;
	}
	ListNode* pre = head;
	ListNode* jHead = new ListNode(0);
	ListNode* oHead = new ListNode(0);
	
	//奇数位升序,偶数位降序, 返回升序
	ListNode* cur1 = jHead;
	int num = 1;
	while (pre) {
		if (num % 2 != 0) {
			ListNode* node = new ListNode(pre->val);
			cur1->next = node;
			cur1 = cur1->next;
		}
		else if (num % 2 == 0) { 
			ListNode* cur2 = oHead;
			ListNode* node = new ListNode(pre->val);
			if(cur2->next == nullptr){
				cur2->next = node;
			}
			else {
				ListNode* next = cur2->next;
				cur2->next = node;
				node->next = next;
			}
		}
		pre = pre->next;
		num++;
	}

	//两个有序链表合并
	
	ListNode* pre2 = oHead->next;
	while (pre2) {
		ListNode* pre1 = jHead->next;
		ListNode* cur = jHead;
		while (pre1) {
			if (pre2->val < pre1->val) {
				ListNode* node = new ListNode(pre2->val);
				cur->next = node;
				node->next = pre1;
				break;
			}
			if (pre1->next != nullptr) {
				if ((pre2->val > pre1->val) && (pre2->val < pre1->next->val)) {
					ListNode* next = pre1->next;
					ListNode* node = new ListNode(pre2->val);
					pre1->next = node;
					node->next = next;
					break;
				}
			}
			else {
				ListNode* node = new ListNode(pre2->val);
				pre1->next = node;
				node->next = nullptr;
				break;
			}
			pre1 = pre1->next;
			cur = cur->next;
		}
		pre2 = pre2->next;
	}
	return jHead->next;
}

15、判断一个链表是否为回文结构

NC96 判断一个链表是否为回文结构

bool isPail(ListNode* head) {
	if (head == nullptr || head->next == nullptr) {
		return true;
	}
	vector<int> vec;
	while (head) {
		vec.push_back(head->val);
		head = head->next;
	}

	for (size_t i = 0; i < sizeof(vec); ++i) {
		if (vec[i] == vec[vec.size() - 1 - i]) {
			if (i >= vec.size() - 1 - i) {
				break;
			}
			else {
				continue;
			}
		}
		else {
			return false;
		}
	}
	return true;
}

16、链表的奇偶重排

NC133 链表的奇偶重排

ListNode* oddEvenList(ListNode* head) {
	if (head == nullptr) {
		return head;
	}
	ListNode* jHead = new ListNode(0);
	ListNode* oHead = new ListNode(0);
	ListNode* cur1 = jHead;
	ListNode* cur2 = oHead;

	int num = 1;
	while (head) {
		ListNode* node = new ListNode(head->val);
		if (num % 2 != 0) {
			cur1->next = node;
			cur1 = cur1->next;
		}
		else{
			cur2->next = node;
			cur2 = cur2->next;
		}
		num++;
		head = head->next;
	}

	cur1->next = oHead->next;
	return jHead->next;
}

17、给单链表加一

NC189 给单链表加一

ListNode* reverseList(ListNode* head) {
	ListNode* pre = head;
	ListNode* cur = nullptr;
	ListNode* nex = nullptr;
	while (pre) {
		nex = pre->next;
		pre->next = cur;
		cur = pre;
		pre = nex;
	}
	return cur;
}

ListNode* plusOne(ListNode* head) {
	if (head == nullptr) {
		ListNode* node = new ListNode(1);
		return node;
	}
	ListNode* pHead = reverseList(head);
	ListNode* cur = pHead;

	int cur_num = 0; //进位标识位
	int num = 0;     //记录数据

	num = pHead->val + 1;
	if (num == 10) {
		cur_num = 1;
		pHead->val = 0;
		while (cur_num) {
			if (cur->next == nullptr) {
				ListNode* node = new ListNode(1);
				cur->next = node;
				cur_num = 0;
			}
			else {
				num = cur->next->val + 1;
				if (num < 10) {
					cur->next->val = num;
					cur_num = 0;
				}
				else {
					cur->next->val = 0;
				}
			}
			cur = cur->next;
		}
	}
	else {
		pHead->val = num;
	}
	return reverseList(pHead);
}

18、环形链表的约瑟夫问题

NC132 环形链表的约瑟夫问题

struct SListNode {
	int val;
	SListNode* pre;
	SListNode* nex;
	SListNode(int x) :
		val(x),
		pre(nullptr),
		nex(nullptr)
	{}
};

int ysf(int n, int m) {
	SListNode* root = new SListNode(0);
	SListNode* cur = root;
	for (int i = 1; i <= n; ++i) {
		SListNode* node = new SListNode(i);
		cur->nex = node;
		node->pre = cur;
		cur = cur->nex;
	}

	root = root->nex;
	root->pre = cur;
	cur->nex = root;
	
	cur = cur->nex;
	while (cur->nex != cur) {
		for (int i = 1; i <= m; ++i) {
			cur = cur->nex;
		}
		SListNode* node = cur->pre->pre;
		cur->pre = node;
		node->nex = cur;
	}
	return cur->val;
}

19、划分链表

NC23 划分链表

ListNode* partition(ListNode* head, int x) {
	if (head == nullptr) {
		return head;
	}
	
	ListNode* cur = head;
	ListNode* ret = new ListNode(0);
	ListNode* head_s = new ListNode(0);
	ListNode* head_b = new ListNode(0);
	ListNode* cur_a = head_s;
	ListNode* cur_b = head_b;

	int size_s = 0;
	int size_b = 0;

	while (cur) {
		if (cur->val < x) {
			ListNode* node = new ListNode(cur->val);
			cur_a->next = node;
			cur_a = cur_a->next;
			size_s++;
		}
		else if (cur->val >= x) {
			ListNode* node = new ListNode(cur->val);
			cur_b->next = node;
			cur_b = cur_b->next;
			size_b++;
		}
		cur = cur->next;
	}

	if (size_s && size_b) {
		cur_a->next = head_b->next;
		ret->next = head_s->next;
	}
	else {
		ret->next = head;
	}
	return ret->next;
}

20、删除链表的倒数第n个节点

BM9 删除链表的倒数第n个节点

ListNode* removeNthFromEnd(ListNode* head, int n) {
    // write code here
    ListNode* ret = new ListNode(0);
    ret->next = head;
    ListNode* slow = ret;
    ListNode* cur = head;
    ListNode* pre = head;
    while(n > 0){
        cur = cur->next;
        n--;
    }
    while(cur){
        cur = cur->next;
        slow = slow->next;
        pre = pre->next;
    }
    slow->next = pre->next;
    return ret->next;
}
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_ClivenZ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值