目录

  • 1 题目链接
  • 2 题目
  • 3 解答
  • 3.1 方案一(统计链表长度)
  • 思路
  • 代码
  • 3.2 方案二(双指针)
  • 思路
  • 代码



1 题目链接

https://www.nowcoder.com/exam/oj/ta?page=1&tpId=13&type=265

2 题目

java 字符串 倒数第二个a的位置_链表


java 字符串 倒数第二个a的位置_java 字符串 倒数第二个a的位置_02

3 解答

3.1 方案一(统计链表长度)

思路

  1. 统计整个链表的长度len
  2. 用len和题目所给的k进行比较,有三种情况
  • len < k
  • 这种情况是不存在的,比如:链表长度是5,返回倒数第7个节点…
  • len = k
  • 这是这道题特殊情况,比如:链表长度是5,返回倒数第五个节点,也就是返回链表的头节点,直接将传入的参数返回即可
  • len > k
  • 这是这道题的一般情况,比如:链表的长度是5,返回倒数第2个节点,则需要从节点开始,调用tmp = tmp.next这句代码len-k

代码

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param pHead ListNode类
     * @param k     int整型
     * @return ListNode类
     */
    public ListNode FindKthToTail(ListNode pHead, int k) {

		//用len来记录链表的长度
        int len = 0;
        ListNode tmp = pHead;
        while (tmp != null) {
            len++;
            tmp = tmp.next;
        }
        
        if (k > len) {
            return null;
        }

        if (k == len) {
            return pHead;
        }

        tmp = pHead;
        for (int i = 1; i <= (len - k); i++) {
            tmp = tmp.next;
        }
        return tmp;
    }
}

3.2 方案二(双指针)

思路

这个题目也可以反过来思考,假设有两个指针,其中一个指针就指在倒数第k个节点上,另一个指针指在链表的结尾。

假设k=2,也就是返回倒数第二个节点,按照上面的思路,可以画出下图,两个指针之间的距离正好也是2。

java 字符串 倒数第二个a的位置_java 字符串 倒数第二个a的位置_03

现在把slow和fast两个指针一起向前移动,让slow放在头节点的位置,slow和fast两指针之间的间隔保持不变。

java 字符串 倒数第二个a的位置_java_04

再往前倒推一步,刚开始的时候slow和fast都指向第一个节点,然后fast先向后移动k次,然后slow和fast再一起移动,这样,当fast指向链表末尾(也就是在最后一个节点,再执行一次.next操作后)的时候,slow指向的位置就是倒数第k个节点。

下面是动态展示:

java 字符串 倒数第二个a的位置_链表_05

代码

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * @param pHead ListNode类
     * @param k     int整型
     * @return ListNode类
     */
    public ListNode FindKthToTail(ListNode pHead, int k) {

        ListNode fast = pHead;
        //fast指针先走k步
        for (int i = 1; i <= k; i++) {
            if (fast != null) {
                fast = fast.next;
            } else {
                //说明 k 大于 链表的长度
                return null;
            }
        }

        ListNode slow = pHead;
        while (fast != null) {
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }
}