《剑指Offer》Java刷题 NO.14 链表中倒数第K个结点

《剑指Offer》Java刷题 NO.13 调整数组顺序使奇数位于偶数之前(链表、两指针配合)

传送门:《剑指Offer刷题总目录》

时间:2020-02-22
题目:
输入一个链表,输出该链表中倒数第k个结点。


思路:
设置两个指针,第一个先比第二个快k-1,然后两个指针一起后移,当第一个指针到尾端时,第一个指针正好在倒数第k个
注意:

  1. head是否为null
  2. k是否为0
  3. k是否大于链表总的结点数

变形:

  1. 找出链表中间结点:第一个指针正常移动(每次移动一个),第二个指针是第一个速度的2倍(每次移动两个),当第二个指针到达尾端时,第一个指针正好在中间
  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));
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值