链表相关算法总结

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。因为在编写程序时,经常用来评估代码能力–包括代码规范性、完整性、鲁棒性。


本文按照论文按照题目进行距离总结,题目列表如下:
1、环形链表插值问题
2、当前访问节点删除问题
3、链表中荷兰国旗问题
4、**单链表的k区间逆序问题
5、复杂结构链表的复制
6、单链表判断是否有环
7、无环单链表判断相交
8、有环单链表相交
9、**单链表相交


内容详述

1、环形链表插值问题
描述:有一个整数val,如何在节点值有序的环形链表中插入一个节点值为val的节点,并且保证这个环形单链表依然有序。
测试样例:{1,2,4,5,7},3
返回结果:{1,2,3,4,5,7}
分析:考察程序的鲁棒性和完整性,要考虑插入值val应当插入的位置:val小于头部节点的值,插入到头部前面;当val大于头部节点值,且小于最小值时,应插入到头部和尾部之间第一比他大的节点之前;当val大于循环链表的最大值,则插入到尾部之后。
示例代码:无
总结:无
2、当前访问节点删除问题
描述:实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点。给定带删除的节点,请执行删除操作,若该节点为尾节点,返回false,否则返回true
分析:链表中,要删除一个元素,经常是在知道删除节点的前一个节点的情况下进行操作的。当前只知道要删除节点,因此这个问题只能另寻思路:将该节点的下一个节点的值替换当前值,然后删除后面一个节点,就能完成任务。但是,当删除节点是尾节点时,则不能这么干,也不能直接将当前节点设置为null(这样最会抛出异常ava.lang.StackOverflowError)。
示例代码:无
总结:无
3、链表中荷兰国旗问题
描述:对于一个链表,我们需要用一个特定阈值完成对它的分化,使得小于等于这个值的结点移到前面,大于该值的结点在后面,同时保证两类结点内部的位置关系不变。给定一个链表的头结点head,同时给定阈值val,请返回一个链表,使小于等于它的结点在前,大于等于它的在后,保证结点值不重复。
分析:时间复杂度为O(n)的方法,空间复杂度为O(1)。解题思路是,将链表拆分成两个链表,一个是小于val的链表L1和大于val的链表L2,然后合并两个链表。
示例代码:无
总结:无
4、单链表的k区间逆序问题
描述:有一个单链表,请设计一个算法,使得每K个节点之间逆序,如果最后不够K个节点一组,则不调整最后几个节点。例如链表1->2->3->4->5->6->7->8->null,K=3这个例子。调整后为,3->2->1->6->5->4->7->8->null。因为K==3,所以每三个节点之间逆序,但其中的7,8不调整,因为只有两个节点不够一组。给定一个单链表的头指针head,同时给定K值,返回逆序后的链表的头指针。
分析:使用两个指针pre和lst,分别记录反转区域的头指针和尾指针,当lst和pre相距k时,就对pre和lst界定的范围进行反转。当lst到达尾节点时,就结束了操作。
示例代码

public ListNode inverse1(ListNode head, int k) {
	if (head == null|| k < 2) { return head; }
	ListNode pre = head;
	ListNode las = head;
	ListNode curHead = null;
	ListNode preLast = null;
	int cnt = k;
	while (las != null) {
		if (--cnt == 0) {
			if (curHead == null) {
				curHead = inversek(pre, las);
				preLast = pre;
				head = curHead;
			} else {
				curHead = inversek(pre, las);
				preLast.next = curHead;
				preLast = pre;
			}
			cnt = k;
			if (pre.next == null)
				break;
			pre = pre.next;
			las = pre;
		} else {
			las = las.next;
		}
	}
	return head;
}
public ListNode inversek(ListNode pre, ListNode las) {
	ListNode head = las.next;
	ListNode cur = pre;
	ListNode nxt = null;
	ListNode end = las.next;
	while (end != cur) {
		nxt = cur.next;
		cur.next = head;
		head = cur;
		cur = nxt;
	}
	return head;
}

总结:熟练掌握单链表的旋转。
5、复杂结构链表的复制
描述:输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点)。
分析:解决思路,首先在原始节点的后面复制一份,形成一个长度为原来两倍的链表;然后,构造random指针,每个新构建的节点的random指向的节点是前一个节点random之后的节点;最后将要返回的结果从构建结果中分离出来。

《链表相关算法总结》
原始链表

《链表相关算法总结》

构建结果

示例代码

public static RandomListNode Clone(RandomListNode pHead) {
	if (pHead == null) {
		return pHead;
	}
	// 复制位置节点
	RandomListNode ptr = pHead;
	while (ptr != null) {
		RandomListNode item = new RandomListNode(ptr.label);
		item.next = ptr.next;
		ptr.next = item;
		ptr = ptr.next.next;
	}
	// 连接random指针
	ptr = pHead;
	RandomListNode nxt = null;
	while (ptr != null) {
		nxt = ptr.next;
		nxt.random = ptr.random != null ? ptr.random.next : null;
		ptr = nxt.next == null ? null : nxt.next;
	}
	RandomListNode retHead = pHead.next;
	RandomListNode cur = pHead;
	while (cur != null) {
		ptr = cur.next.next;
		nxt = cur.next;
		cur.next = nxt.next;
		nxt.next = ptr == null ? null : ptr.next;
		cur = ptr;
	}
	return retHead;
}

总结:无

6、单链表判断是否有环

描述:如何判断一个单链表是否有环?有环的话返回进入环的第一个节点的值,无环的话返回-1。如果链表的长度为N,请做到时间复杂度O(N),额外空间复杂度O(1)。

分析:设置两个指针fastslowfast指针每次走两步,slow指针每次走一步。如果链表无环,fast首先到达尾节点,返回false;否则,fast必然会和slow交于某节点,同时,让fast回到头部,fastslow每次移动一步,当fastslow再次重逢的节点就是入环的第一个节点。

示例代码:无

总结:无

7、无环单链表判断相交

描述:现在有两个无环单链表,若两个链表的长度分别为mn,请设计一个时间复杂度为O(n + m),额外空间复杂度为O(1)的算法,判断这两个链表是否相交。给定两个链表的头结点headAheadB,请返回一个bool值,代表这两个链表是否相交。

分析:分别遍历每个链表得到每个链表的长度lenAlenB,然后指向较长的链表的指针先走steps(|lenALenB|),然后两个链表指针同时移动,当两个指针相等时,说明这两个链表相交,否则不相交。

示例代码:无

总结:无

8、有环单链表相交

描述:如何判断两个有环单链表是否相交?相交的话返回第一个相交的节点,不想交的话返回空。如果两个链表长度分别为N和M,请做到时间复杂度O(N+M),额外空间复杂度O(1)。

分析:如果两个有环链表相交,相交的位置会发生在入环节点之前和入环之后。因此,要求取每个链表的入环节点N1和N2,如果两个节点相等,那么两个有环链表相交;然后,判断连个节点是否环中相交。

《链表相关算法总结》


示例代码:无

总结:无
9、单链表相交
描述:给定两个单链表的头节点head1和head2,如何判断两个链表是否相交?相交的话返回true,不想交的话返回false。
分析:这个问题总结前几种情况:两个都无环,判断相交;一个有环,另一个无环,绝对不想交;两个都有环,判断相交。

示例代码:无
总结:无

    原文作者:victor_lwx
    原文地址: https://blog.csdn.net/qq_34739984/article/details/51530941
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞