一、题目
————————————————
题目描述
输入一个链表,输出该链表中倒数第k个结点。
————————————————
二、思路
————————————————
方法一:
设链表的长度为 N。设置两个指针 P1 和 P2,先让 P1 移动 K 个节点,则还有 N - K 个节点可以移动。此时让 P1 和 P2 同时移动,可以知道当 P1 移动到链表结尾时,P2 移动到第 N - K 个节点处,该位置就是倒数第 K 个节点。
————————————————
方法二:利用栈,先进后出
————————————————
三、解决问题
————————————————
测试算例
1.功能测试(第k个结点分别在链表的中间,头结点和尾结点)
2.特殊测试(头结点为null,k超出范围)
————————————————
package swordoffer;
/**
* @author LQ
* @version 1.0
* @date 2020\3\11 0011 10:15
*/
//输入一个链表的头结点,从尾到头反过来打印出每个结点的值。结点定义如下:
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
package swordoffer;
/**
* @author LQ
* @version 1.0
* @date 2020-03-20 20:15
*/
import java.util.Stack;
/**
* 题目:
* 输入一个链表,输出该链表中倒数第k个结点。
* 为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。
* 例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。
* 这个链表的倒数第3个结点是值为4的结点。
*/
public class Solution17 {
public static void main(String[] args) {
Solution17 demo = new Solution17();
System.out.println("==============================");
System.out.println("test1");
demo.test1();
System.out.println("==============================");
System.out.println("test2");
demo.test2();
System.out.println("==============================");
System.out.println("test3");
demo.test3();
System.out.println("==============================");
System.out.println("test4");
demo.test4();
System.out.println("==============================");
System.out.println("test5");
demo.test5();
System.out.println("==============================");
System.out.println("test6");
demo.test6();
System.out.println("==============================");
}
//方法1:利用两个相距为k-1的指针
public ListNode FindKthToTail1(ListNode head,int k) {
//不满足的条件
if(null == head || k <= 0){
return null;
}
ListNode pAhead = head;
//1.先让 pAhead 移动 K 个节点,则还有 N - K 个节点可以移动
while (pAhead != null && k-- > 0){
pAhead = pAhead.next;
}
//给定k的长度大于链表实际长度
if (k > 0){
return null;
}
//2.此时让 pAhead 和 pBehind 同时移动
//可以知道当 pAhead 移动到链表结尾时,pBehind 移动到第 N - K 个节点处
//该位置就是倒数第 K 个节点
ListNode pBehind = head;
while (pAhead != null) {
pAhead = pAhead.next;
pBehind = pBehind.next;
}
return pBehind;
}
//方法2:利用栈-先进后出
public ListNode FindKthToTail2(ListNode head,int k) {
if(null == head || k <= 0){
return null;
}
int numbOfList = 1;
Stack<ListNode> st = new Stack<ListNode>();
st.push(head);
ListNode node = head.next;
while(node != null){
numbOfList++;
st.push(node);
node = node.next;
}
if(k > numbOfList){
return null;
}else{
for (int i = 1; i <= k; i++) {
node = st.pop();
}
return node;
}
}
//=====================测试代码=======================
/*
* null
*/
void test1() {
ListNode head1=null;
ListNode result1=FindKthToTail1(head1, 1);
if(result1 == null)
System.out.println("test1 passed!");
else
System.out.println("test1 failed!");
System.out.println("===========方法二:利用栈-先进后出============");
ListNode head2=null;
ListNode result2=FindKthToTail2(head2, 1);
if(result2 == null)
System.out.println("test1 passed!");
else
System.out.println("test1 failed!");
}
/*
* k超出范围
*/
void test2() {
ListNode head=new ListNode(2);
ListNode result=FindKthToTail1(head, 2);
if(result == null)
System.out.println("test2 passed!");
else
System.out.println("test2 failed!");
System.out.println("===========方法二:利用栈-先进后出============");
ListNode head2=new ListNode(2);
ListNode result2=FindKthToTail2(head2, 2);
if(result2 == null)
System.out.println("test2 passed!");
else
System.out.println("test2 failed!");
}
/*
* 单个结点
*/
void test3() {
ListNode head=new ListNode(1);
ListNode result=FindKthToTail1(head, 1);
if(result.val==1)
System.out.println("test3 passed!");
else
System.out.println("test3 failed!");
System.out.println("===========方法二:利用栈-先进后出============");
ListNode head2=new ListNode(1);
ListNode result2=FindKthToTail2(head2, 1);
if(result2.val == 1)
System.out.println("test3 passed!");
else
System.out.println("test3 failed!");
}
/*
* 尾结点
*/
void test4() {
ListNode node1=new ListNode(1);
ListNode node2=new ListNode(2);
ListNode node3=new ListNode(3);
ListNode node4=new ListNode(4);
node1.next=node2;
node2.next=node3;
node3.next=node4;
ListNode result=FindKthToTail1(node1, 1);
if(result.val==4)
System.out.println("test4 passed!");
else
System.out.println("test4 failed!");
System.out.println("===========方法二:利用栈-先进后出============");
ListNode result2=FindKthToTail2(node1, 1);
if(result2.val==4)
System.out.println("test4 passed!");
else
System.out.println("test4 failed!");
}
/*
* 中间结点
*/
void test5() {
ListNode node1=new ListNode(1);
ListNode node2=new ListNode(2);
ListNode node3=new ListNode(3);
ListNode node4=new ListNode(4);
node1.next=node2;
node2.next=node3;
node3.next=node4;
ListNode result=FindKthToTail1(node1, 2);
if(result.val==3)
System.out.println("test5 passed!");
else
System.out.println("test5 failed!");
System.out.println("===========方法二:利用栈-先进后出============");
ListNode result2=FindKthToTail2(node1, 2);
if(result2.val==3)
System.out.println("test5 passed!");
else
System.out.println("test5 failed!");
}
/*
* 头结点
*/
void test6() {
ListNode node1=new ListNode(1);
ListNode node2=new ListNode(2);
ListNode node3=new ListNode(3);
ListNode node4=new ListNode(4);
node1.next=node2;
node2.next=node3;
node3.next=node4;
ListNode result=FindKthToTail1(node1, 4);
if(result.val==1)
System.out.println("test6 passed!");
else
System.out.println("test6 failed!");
System.out.println("===========方法二:利用栈-先进后出============");
ListNode result2=FindKthToTail2(node1, 4);
if(result2.val==1)
System.out.println("test6 passed!");
else
System.out.println("test6 failed!");
}
}
输出
============================== test1 test1 passed! ===========方法二:利用栈-先进后出============ test1 passed! ============================== test2 test2 passed! ===========方法二:利用栈-先进后出============ test2 passed! ============================== test3 test3 passed! ===========方法二:利用栈-先进后出============ test3 passed! ============================== test4 test4 passed! ===========方法二:利用栈-先进后出============ test4 passed! ============================== test5 test5 passed! ===========方法二:利用栈-先进后出============ test5 passed! ============================== test6 test6 passed! ===========方法二:利用栈-先进后出============ test6 passed! ============================== Process finished with exit code 0
————————————————
努力也是需要学习的,别再让你的努力,只感动了自己!愿你的每一次努力,都能为自己和别人创造价值。

京公网安备 11010502036488号