NowCoderTOP7-11——持续更新ing
Posted 王嘻嘻-
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了NowCoderTOP7-11——持续更新ing相关的知识,希望对你有一定的参考价值。
TOP7 链表中环的入口结点
/**
* 7 链表中环的入口结点
* 假设从头节点到环的入口节点的前一个节点一共有a个,环中的节点有b个,设fast指针走过的节点数是f,slow指针走过的节点数是s,那么有以下两个结论:
* f = 2 * s (即快指针走过的节点数一定是慢指针的两倍)
* f = s + nb (当两者相遇时,快指针一定已经绕环走了n圈)
* 由上面两个等式可以得出,f = 2nb,s = nb
* 故可知,两指针相遇时,慢指针已经走了nb步,已知我们要走到入口节点,需要走a + kb步,而这时s = nb只要再走a即可到达入口,我们把快指针移动
* 到头节点,然后两个指针一步一步往后走,当它们相遇时所处的位置就是入口节点
* step 1:判断链表中是否有环中的方法判断链表是否有环,并找到相遇的节点。
* step 2:慢指针继续在相遇节点,快指针回到链表头,两个指针同步逐个元素逐个元素开始遍历链表。
* step 3:再次相遇的地方就是环的入口。
**/
public class top7
//判断有没有环,返回相遇的地方
public ListNode hasCycle(ListNode head)
//先判断链表为空的情况
if (head == null) return null;
//快慢双指针
ListNode fast = head;
ListNode slow = head;
//如果没环快指针会先到链表尾
while (fast != null && fast.next != null)
//快指针移动两步
fast = fast.next.next;
//慢指针移动一步
slow = slow.next;
//相遇则有环,返回相遇的位置
if (fast == slow) return slow;
//到末尾说明没有环,返回null
return null;
public ListNode EntryNodeOfLoop(ListNode pHead)
ListNode slow = hasCycle(pHead);
//没有环
if (slow == null) return null;
//快指针回到表头
ListNode fast = pHead;
//再次相遇即是环入口
while (fast != slow)
fast = fast.next;
slow = slow.next;
return slow;
TOP8 链表中倒数最后k个结点
/**
* 8 链表中倒数最后k个结点
* step 1:准备一个快指针,从链表头开始,在链表上先走k步。
* step 2:准备慢指针指向原始链表头,代表当前元素,则慢指针与快指针之间的距离一直都是k。
* step 3:快慢指针同步移动,当快指针到达链表尾部的时候,慢指针正好到了倒数k个元素的位置。
**/
public class top8
public ListNode FindKthToTail (ListNode pHead, int k)
ListNode fast = pHead;
ListNode slow = pHead;
// 快指针先走 K 步
for (int i = 0; i < k; i++)
if (fast != null) fast = fast.next;
// 说明链表长度小于 K
else return null;
// 当快指针不为空,快慢指针同步前进
while (fast != null)
fast = fast.next;
slow = slow.next;
// 快指针为空,说明到头了,慢指针指向的就是倒数第 k 个节点的位置
return slow;
TOP9 删除链表的倒数第n个节点
public class Solution
/**
* @param head ListNode类
* @param n int整型
* @return ListNode类
*/
public ListNode removeNthFromEnd (ListNode head, int n)
// 添加表头,要将其保存下来,防止被修改
// 返回表头的下一个节点
ListNode res = new ListNode(-1);
res.next = head;
ListNode pre = res;
ListNode fast = head;
ListNode slow = head;
// 先让快指针向前走k步
for(int i = 0; i < n ; i++)
if(fast != null) fast = fast.next;
// 说明链表长度小于k
else return null;
while(fast != null)
fast = fast.next;
pre = pre.next;
slow = slow.next;
// 此时快指针已经走到空,慢指针指向的节点就是将要删除的节点
pre.next = slow.next;
return res.next;
TOP10 两个链表的第一个公共结点
public class Solution
public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2)
// ListNode l1 = pHead1;
// ListNode l2 = pHead2;
// while(l1 != l2)
// l1 = (l1 == null) ? pHead2 : l1.next;
// l2 = (l2 == null) ? pHead1 : l2.next;
//
// return l1;
// 计算两个链表的长度
int len1 = length(pHead1);
int len2 = length(pHead2);
// 如果两个链表的长度不一样,节点多的先走,直到他们的长度一样
while(len1 != len2)
if(len1 > len2)
pHead1 = pHead1.next;
len1 --;
else
pHead2 = pHead2.next;
len2 --;
// 此时两个链表长度相等,比较其元素大小
while(pHead1 != pHead2)
pHead1 = pHead1.next;
pHead2 = pHead2.next;
//走到最后,最终会有两种可能,一种是head1为空,
//也就是说他们俩不相交。还有一种可能就是head1
//不为空,也就是说head1就是他们的交点
return pHead1;
private int length(ListNode head)
int n = 0;
while(head != null)
head = head.next;
n++;
return n;
TOP11 链表相加(二)
public class Solution
/**
* @param head1 ListNode类
* @param head2 ListNode类
* @return ListNode类
*/
public ListNode addInList (ListNode head1, ListNode head2)
if(head1 == null) return head2;
if(head2 == null) return head1;
ListNode l1 = reverse(head1);
ListNode l2 = reverse(head2);
ListNode res = null;
int c = 0; // 进位
// 如果 c > 0 那么就说明存在进位还得插入一个节点
while(l1 != null || l2 != null || c > 0)
int v1 = l1 != null ? l1.val : 0;
int v2 = l2 != null ? l2.val : 0;
int total = v1 + v2 + c; //当前这一位的总和
c = total / 10;
// 进行当前节点的插入
ListNode temp = new ListNode(total % 10); // 当前位
temp.next = res;
res = temp;
if(l1 != null) l1 = l1.next;
if(l2 != null) l2 = l2.next;
return res;
// 翻转链表
public ListNode reverse(ListNode head)
if(head == null) return null;
ListNode pre = null;
while(head != null)
ListNode next = head.next;
head.next = pre;
pre = head;
head = next;
return pre;
以上是关于NowCoderTOP7-11——持续更新ing的主要内容,如果未能解决你的问题,请参考以下文章