leetcode 61.旋转链表
给定一个链表,旋转链表,将链表每个节点向右移动 k 个位置,其中 k 是非负数。
示例 1:
输入: 1->2->3->4->5->NULL, k = 2
输出: 4->5->1->2->3->NULL
解释:
向右旋转 1 步: 5->1->2->3->4->NULL
向右旋转 2 步: 4->5->1->2->3->NULL
解题:找到关键节点的位置,从中间断链连接
public ListNode rotateRight(ListNode head, int k) {
if(head == null || head.next == null)
return head;
ListNode end = head;
int len = 0;
while ( end.next != null ){
end = end.next;
len++;
}
len++;
k = k % len;
if(k == 0 )
return head;
ListNode temp = head;
for(int i = len;i > k + 1;i--){
temp = temp.next;
}
end.next = head;
head = temp.next;
temp.next = null;
return head;
}
leetcode 141.环形链表
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
示例:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
解题:设定一个快指针和慢指针,假如链表有环,快指针将追上慢指针
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null)
return false;
ListNode fast = head.next;
ListNode slow = head;
while(fast != null){
if(fast == slow){
return true;
} else {
fast = fast.next;
if(fast == null)
return false;
else {
fast = fast.next;
slow = slow.next;
}
}
}
return false;
}
leetcode 142.环形链表II
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
解题:起始位置到入环节点的距离等于相遇节点到入环节点的距离,因此接上题,使用快慢指针找到两指针相遇点,求指针从开始节点出发和从相遇位置出发的相遇节点
public ListNode detectCycle(ListNode head) {
if(head == null || head.next == null)
return null;
ListNode fast = head;
ListNode slow = head;
ListNode meet = null;
while(fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
meet = fast;
fast = head;
break;
}
}
while(meet != null ) {
if(meet == fast)
break;
fast = fast.next;
meet = meet.next;
}
return meet;
}
leetcode 160相交链表
编写一个程序,找到两个单链表相交的起始节点。
如下面的两个链表:
在节点 c1 开始相交。
注意:
如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
解题:双指针法,假设两个链表相交,设A的长度为a+c,B的长度为b+c(a,b分别为不相交链表长度,c为公共个链表长度),那么将链表A延长b+c,链表B延长a+c,两指针同时向后移动,必定在相交节点相遇,否则为null
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode cursorA = headA;
ListNode cursorB = headB;
if (cursorA == null || cursorB == null)
return null;
while (cursorA != cursorB){
if (cursorA == null)
cursorA = headB;
else
cursorA = cursorA.next;
if (cursorB == null)
cursorB = headA;
else
cursorB = cursorB.next;
}
return cursorA;
}
leetcode 23.合并k个排序链表
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例:
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
解题:采用优先级队列,将所有链表的队首入列,每次取出当前最小队首元素,直到所有链表为空
public ListNode mergeKLists(ListNode[] lists) {
ListNode head = null,end = null,temp = null;
Queue<ListNode> p = new PriorityQueue<>((a,b)->a.val-b.val);
for(int i = 0;i < lists.length;i++){
if(lists[i] != null)
p.add(lists[i]);
}
while (!p.isEmpty()){
temp = p.poll();
if(head == null){
head = temp;
} else {
end.next = temp;
}
end = temp;
if(temp.next != null){
p.add(temp.next);
}
end.next = null;
}
return head;
}