题目
找出单向链表中的一个节点,该节点到尾指针的距离为K。链表的倒数第0个结点为链表的尾指针。要求时间复杂度为O(n)。
链表结点定义如下:
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
}
链表节点的值初始化为1,2,3,4,5,6,7。
输入描述:
该节点到尾指针的距离K
输出描述:
返回该单向链表的倒数第K个节点,输出节点的值
示例1
输入:2
输出:6
备注:
请自觉实现一个链表,将1到7依次加入链表,然后再寻找倒数第K个节点。要求加节点与找节点的操作复杂度均为O(n)。
题目来源
小米2019秋招,测试开发岗
分析
有两种解题思路。
解法1:引入栈,将链表结点一一入栈,再出栈k个元素,即可找到链表的倒数第k个结点。
解法2:使用双指针,p1和p2相距k个结点,然后p1,p2都后移,当p1指向null时,p2指针正好指向倒数第k个结点。
思路如下图:
方法1代码
import java.util.Stack;
import java.util.Scanner;
//import ListNode;
class ListNode{
int m_nKey; //节点值
ListNode m_pNext=null; //指针
ListNode(int m_nKey){
this.m_nKey=m_nKey;
}
}
public class Main{
public static ListNode FindKthToTail(ListNode listNode,int k){
//寻找距尾指针的距离为K的节点值
int count=1; //i在后面计数时用到
ListNode result=null; //result为返回的结果
Stack<ListNode> stack=new Stack<>(); //引入栈空间
while(listNode!=null){
stack.push(listNode); //将链表的数据一一入栈
listNode=listNode.m_pNext;
}
//此时找距离尾指针为K的节点即是需要出栈K次得到的节点
while(count<k){
stack.pop();
count=count+1;
}
if(!stack.isEmpty()){
result=stack.pop();
}
return result;
}
public static void main(String args[]){
//先构造节点为1-7的链表
ListNode head=new ListNode(1); //头节点
ListNode p=null; //q为p的下一个节点
ListNode q=null;
p=head;
for(int i=2;i<=7;i++){ //将剩余6个节点加入链表
q=new ListNode(i);
p.m_pNext=q;
p=q;
p.m_pNext=null;
}
Scanner sc=new Scanner(System.in);
//System.out.println("请输入k值:");
int k=sc.nextInt();
ListNode result=FindKthToTail(head,k); //调用函数
sc.close();
System.out.println(result.m_nKey);
}
}
方法2代码
import java.util.Stack;
import java.util.Scanner;
//import ListNode;
class ListNode{
int m_nKey; //节点值
ListNode m_pNext=null; //指针
ListNode(int m_nKey){
this.m_nKey=m_nKey;
}
}
public class Main{
public static ListNode FindKthToTail(ListNode pHead,int k){
//寻找距尾指针的距离为K的节点值
ListNode p1 = pHead; //设置指针p1
ListNode p2 = pHead; //设置指针p2
//指针p1与指针p2的间距为k
int i=0;
while(i < k){
p1 = p1.m_pNext; //将p1指针后移
i++;
}
while(p1 != null){
p1 = p1.m_pNext;
p2 = p2.m_pNext;
}
return p2; //当p1指向null时,p2指向倒数第k个结点
}
public static void main(String args[]){
//先构造节点为1-7的链表
ListNode head=new ListNode(1); //头节点
ListNode p=null; //q为p的下一个节点
ListNode q=null;
p=head;
for(int i=2;i<=7;i++){ //将剩余6个节点加入链表
q=new ListNode(i);
p.m_pNext=q;
p=q;
p.m_pNext=null;
}
Scanner sc=new Scanner(System.in);
//System.out.println("请输入k值:");
int k=sc.nextInt();
ListNode result=FindKthToTail(head,k); //调用函数
sc.close();
System.out.println(result.m_nKey);
}
}