- 此题有两个方法,解题时必须考虑数组越界问题,使用if进行检查
方法一:快慢指针
- 链表长度未知的情况下,可以用一个指针找到输出的点位,再用另一个指针置于链表最后,相当于找到了链表的“长度”,此方法没有占用额外的储存空间,空间复杂度为O(1)
- 定义两个指针fast和slow,初始都置于头节点处
- fast先向前移动k步,这时两个指针之间相隔k个单位
- 再将两个指针同步移动,直至fast移动至末尾,移动结束
此时两个指针之间所夹住的部分就是要导出的链表,使用slow指针即可获取
- 注意:数组越界问题
判断k是否大于链表长度:也即判断fast向前移动k步的过程中会不会提前到达链表末尾
Java核心代码:
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
if(k==0||pHead==null)return null;
//1. 定义两个指针,指向头结点
ListNode fast = pHead;
ListNode slow = pHead;
//2. fast循环向前移动k次
for(int i=0;i<k;i++){
// k越界检查
if(fast==null)return null;
fast=fast.next;
}
//3. 两指针同步移动,直至fast到达末尾
while(fast!=null){
fast=fast.next;
slow=slow.next;
}
return slow;
}
方法二:利用栈存储
开辟了栈空间,空间复杂度为O(n)
public ListNode FindKthToTail (ListNode pHead, int k) {
// write code here
//非空判断
if(k==0||pHead==null)return null;
Stack<ListNode> stack = new Stack<>();
while(pHead!=null){
//链表入栈
stack.push(pHead);
pHead = pHead.next;
}
//越界判断,判断之后再进行pop
if(k>stack.size())return null;
//必须先拿出一个,在循环取出时,才能连接成链表
ListNode firstNode = stack.pop();
while(--k>0){
// 拿出一个栈顶元素
ListNode temp = stack.pop();
//链接结点:将栈顶存储的此链表元素置于firstNode之前
//每次拿出一个最新的栈顶元素放在最前面,按顺序存放
temp.next = firstNode;
//每次重新设置最新栈顶元素设置为first结点
//firstNode指向链表头结点
firstNode = temp;
}
return firstNode;
}
`