2018.8.9 《剑指Offer》从零单刷个人笔记整理(66题全)目录传送门
题目不难,定义一前一后两个指针,前一个指针比后一个指针快K-1个结点,然后两个指针同步推进,直到前一个指针到达链表尾部,后一个指针所指向的位置就是链表中倒数第K个结点。
需要注意的边界条件:1.指针为null,2.参数为0,3.参数大于结点数
同样的题目还有一些变式:
1.求链表的中间结点——前一个指针比后一个指针速度快一倍的速度即可
2.判断链表是否为环形——前一个指针比后一个指针速度快一倍的速度,如果前一个指针追上了后一个指针,则链表为环形;如果前一个指针先走到了末尾,则非环形。
题目描述
输入一个链表,输出该链表中倒数第k个结点。
JAVA实现:
/**
*
* @author ChopinXBP
* 输入一个链表,输出该链表中倒数第k个结点。
* 注意:1.指针为null,2.参数为0,3.参数大于结点数
*
*/
public class FindKthToTail {
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
}
public static ListNode Solution(ListNode head, int k){
//指针为null或参数为0
if(head == null || k == 0)return null;
ListNode p = head;
ListNode result = head;
while(--k > 0){
if(p.next == null)return null; //参数大于结点数
p = p.next;
}
while(p.next != null){
p = p.next;
result = result.next;
}
return result;
}
}
C++实现示例:
#include "stdafx.h"
#include "..\Utilities\List.h"
ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if(pListHead == NULL || k == 0)
return NULL;
ListNode *pAhead = pListHead;
ListNode *pBehind = NULL;
for(unsigned int i = 0; i < k - 1; ++ i)
{
if(pAhead->m_pNext != NULL)
pAhead = pAhead->m_pNext;
else
{
return NULL;
}
}
pBehind = pListHead;
while(pAhead->m_pNext != NULL)
{
pAhead = pAhead->m_pNext;
pBehind = pBehind->m_pNext;
}
return pBehind;
}
测试代码:
// ====================测试代码====================
// 测试要找的结点在链表中间
void Test1()
{
printf("=====Test1 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 4.\n");
ListNode* pNode = FindKthToTail(pNode1, 2);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试要找的结点是链表的尾结点
void Test2()
{
printf("=====Test2 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 5.\n");
ListNode* pNode = FindKthToTail(pNode1, 1);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试要找的结点是链表的头结点
void Test3()
{
printf("=====Test3 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: 1.\n");
ListNode* pNode = FindKthToTail(pNode1, 5);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试空链表
void Test4()
{
printf("=====Test4 starts:=====\n");
printf("expected result: NULL.\n");
ListNode* pNode = FindKthToTail(NULL, 100);
PrintListNode(pNode);
}
// 测试输入的第二个参数大于链表的结点总数
void Test5()
{
printf("=====Test5 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: NULL.\n");
ListNode* pNode = FindKthToTail(pNode1, 6);
PrintListNode(pNode);
DestroyList(pNode1);
}
// 测试输入的第二个参数为0
void Test6()
{
printf("=====Test6 starts:=====\n");
ListNode* pNode1 = CreateListNode(1);
ListNode* pNode2 = CreateListNode(2);
ListNode* pNode3 = CreateListNode(3);
ListNode* pNode4 = CreateListNode(4);
ListNode* pNode5 = CreateListNode(5);
ConnectListNodes(pNode1, pNode2);
ConnectListNodes(pNode2, pNode3);
ConnectListNodes(pNode3, pNode4);
ConnectListNodes(pNode4, pNode5);
printf("expected result: NULL.\n");
ListNode* pNode = FindKthToTail(pNode1, 0);
PrintListNode(pNode);
DestroyList(pNode1);
}
int _tmain(int argc, _TCHAR* argv[])
{
Test1();
Test2();
Test3();
Test4();
Test5();
Test6();
return 0;
}
#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#