《剑指Offer》Java刷题 NO.13 调整数组顺序使奇数位于偶数之前(链表、两指针配合)
传送门:《剑指Offer刷题总目录》
时间:2020-02-22
题目:
输入一个链表,输出该链表中倒数第k个结点。
思路:
设置两个指针,第一个先比第二个快k-1,然后两个指针一起后移,当第一个指针到尾端时,第一个指针正好在倒数第k个
注意:
- head是否为null
- k是否为0
- k是否大于链表总的结点数
变形:
- 找出链表中间结点:第一个指针正常移动(每次移动一个),第二个指针是第一个速度的2倍(每次移动两个),当第二个指针到达尾端时,第一个指针正好在中间
- 判断链表是不是环形链表:第一个指针正常移动(每次移动一个),第二个指针是第一个速度的2倍(每次移动两个),如果第二个指针追上了第一个指针,则是环形列表,否则第二个指针到达尾端(null),则证明不是环形列表
Java代码:
import java.util.ArrayList;
class ListNode{
int val;
ListNode next=null;
ListNode(int val){
this.val=val;
}
public void setNext(ListNode node){
this.next=node;
}
public static void print(ListNode head){
while(head!=null){
System.out.println(head.val);
head=head.next;
}
}
}
/**
* 输入一个链表,输出该链表中倒数第k个结点。
*/
public class FindKthToTail {
public static ListNode findKthToTail(ListNode head,int k){
if(head==null||k==0) return null;
ListNode fast=head;
ListNode slow=head;
while(--k>0){//需要执行k-1次,不能是k--(会执行k次)
if(fast.next==null) return null;//说明k比总结点数还大
fast=fast.next;
}
while(fast.next!=null) {
slow=slow.next;
fast=fast.next;
}
return slow;
//大神超简洁代码
/*for(;fast.next!=null;fast=fast.next){
if(--k<=0) slow=slow.next;
}
return k>1?null:slow;*/
}
/**
*找出链表中间结点
*/
public static ListNode findMidNode(ListNode head){
if(head==null) return null;
ListNode slow=head;
ListNode fast=head;
while(fast.next.next!=null){
//因为2N/2=N;(2N+1)/2=N,所以只有当fast.next.next!=null时才把slow指针往后移一个
slow=slow.next;
fast=fast.next.next;
}
return slow;
}
/**
*判断链表是不是环形链表
*/
public static boolean isLoopList(ListNode head){
if(head==null) return false;
ListNode slow=head;
ListNode fast=head;
while(fast.next.next!=null){
//因为2N/2=N;(2N+1)/2=N,所以只有当fast.next.next!=null时才把slow指针往后移一个
slow=slow.next;
fast=fast.next.next;
if(fast==slow) break;
}
return fast==slow?true:false;
}
public static void main(String[] args) {
ListNode head = new ListNode(0);
ListNode p = head;
for (int i = 0; i < 5; i++) {
ListNode newnode = new ListNode(i + 1);
p.next = newnode;
p = p.next;
}
p = head;
//head.print(p);
//System.out.println(findMidNode(p).val);
//System.out.println(isLoopList(heapd));
ListNode.print(reverse(p));
}
}