算法
判断循环链表的入环节点(leetcode142)
方法一:使用哈希表,set集合,遍历链表的时候先判断一下是否存在该节点,如果存在那么就是第一个入环的节点
方法二:使用快慢指针,从头节点开始遍历,如果当快慢指针相遇的时候,那么就让快指针又从头节点开始遍历,但是这次一次只需要走一步,慢指针也走异步,当两个指针再次相遇的时候就是他们的入环节点了。
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null || head.next.next == null) {
return null;
}
ListNode n1 = head.next;
ListNode n2 = head.next.next;
while (n1 != n2) {
if (n2.next == null || n2.next.next == null) {
return null;
}
n2 = n2.next.next;
n1 = n1.next;
}
n2 = head;
while (n1 != n2) {
n1 = n1.next;
n2 = n2.next;
}
return n2;
}
}
相交链表
方法一:使用HashSet,分别将A,B两个链表的node加入到链表中去,第二的链表加入时判断是否包含该节点,包含就证明他是第一个节点
ublic class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
HashSet<ListNode> set = new HashSet<>();
while (headA != null) {
set.add(headA);
headA = headA.next;
}
while (headB != null) {
if (set.contains(headB)) {
return headB;
}
headB = headB.next;
}
return null;
}
}
方法二:分别统计两个链表的长度,然后找出长的链表,先遍历他们的差值的长度,然后再将两个链表同时进行遍历,当他们遍历到节点相等就是相交的点。
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode cur1 = headA;
ListNode cur2 = headB;
int n = 0;
while (cur1.next != null) {
n++;
cur1 = cur1.next;
}
while (cur2.next != null) {
n--;
cur2 = cur2.next;
}
if (cur1 != cur2) return null;
cur1 = n > 0 ? headA : headB;
cur2 = cur1 == headA ? headB :headA;
n = Math.abs(n);
while (n != 0) {
n--;
cur1 = cur1.next;
}
while (cur1 != cur2) {
cur1 = cur1.next;
cur2 = cur2.next;
}
return cur1;
}
}
将链表按照某个值左右划分
比如给你一个链表:1,2,5,0,52,33,11,23
请你按照11划分,小于11的节点放在该节点的左边其他放在右边,请你以时间复杂度为O(n)完成该题目
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode sortList(ListNode head) {
//六个节点,存储比较值的小于等于大于的值链表,最后将他们串起来就完成
ListNode Startsn = null;
ListNode Starten = null;
ListNode Midsn = null;
ListNode Miden = null;
ListNode Endsn = null;
ListNode Enden = null;
//创建一个节点来保存没有遍历的节点
ListNode next = null;
while (head != null) {
next = head.next;
head.next = null;
if (head.val < 1) {
if (Startsn == null) {
Startsn = head;
Starten = head;
} else {
Starten.next = head;
Starten = head;
}
} else if (head.val == 1) {
if (Midsn == null) {
Midsn = head;
Miden = head;
} else {
Miden.next = head;
Miden = head;
}
} else {
if (Endsn == null) {
Endsn = head;
Enden = head;
} else {
Enden.next = head;
Enden = head;
}
}
head = next;
}
if (Startsn != null) {
// 如果有小于区域
Starten.next = Midsn;
//下一步,谁去连大于区域的头,
Miden = Miden == null ? Starten : Miden;
}
if (Miden != null) {
Miden.next = Endsn;
}
return Startsn != null ? Startsn : (Endsn != null ? Midsn : Endsn);
}
}