剑指offer14:输入一个链表,输出该链表中倒数第k个结点。

1. 题目描述

  输入一个链表,输出该链表中倒数第k个结点。

2. 思路和方法

  可以用两个指针,一个指针遍历到第k个结点的时候,第二个指针再走到第一个节点,然后两个指针的距离始终保持k-1。这样,当第一个指针的next==NULL,也就是走到最后一个节点的时候,第二个指针对应的位置,就是倒数第k个结点。这样的好处是能够节省一个循环,时间复杂度会相应降低,从Q(2N) 降低到到Q(N)。

  注意,但是需要一个小循环让第一个指针先走到第k个指针。同时也存在结点总数小于k的问题,如果循环还没有进行到k次,而第一个指针的已经是NULL,即走到头了,那么,函数返回NULL

3. C++核心代码

 1 /*
 2 struct ListNode {
 3     int val;
 4     struct ListNode *next;
 5     ListNode(int x) :
 6             val(x), next(NULL) {
 7     }
 8 };*/
 9 class Solution {
10 public:
11     ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
12         ListNode* p = pListHead;
13         ListNode* q = pListHead;
14         int i = 0;
15         for(;p != NULL;i++)
16         {
17             if(i >= k)
18             {
19                 q = q->next;
20             }
21             p = p->next;
22         }
23         return i < k ? NULL:q;
24     }
25 };
View Code

4. C++完整代码

 1 #include <iostream>
 2 
 3 using namespace std;
 4 
 5 struct ListNode {
 6     int val;
 7     struct ListNode *next;
 8     ListNode(int x) :
 9         val(x), next(NULL) {
10     }
11 };
12 
13 class Solution {
14 public:
15     ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
16         ListNode *first = pListHead;    //第一个指针first
17         ListNode *second = pListHead;    //第二个指针second
18         int i;
19         if (first == NULL)
20             return NULL;
21 
22         for (i = 1; i <= k; i++){        //i <= k,让第一个指针先走步
23             if (first->next == NULL)
24                 break;                    //如果已经走到头了,就跳出,否则继续走
25                 first = first->next;
26         }
27         while (first->next != NULL){    //如果第一个指针没有走到头,两个指针想跟着一起走,保持k-1的距离
28             first = first->next;
29             second = second->next;
30         }
31         return second;
32     }
33 };
34 
35 
36 
37 int main()
38 {
39     struct ListNode* p = (struct ListNode*)malloc(sizeof(struct ListNode));
40 
41     struct ListNode* r = (struct ListNode*)malloc(sizeof(struct ListNode));
42     p->val = 0;
43     p->next = NULL;
44 
45     for (int i = 1000; i >= 1; i--){
46         struct ListNode* t = (struct ListNode*)malloc(sizeof(struct ListNode));    //注意,这个空间申请一定要放到for循环内部。
47         t->val = i;    //这种方法是插在头节点p前面,当然也可以插在后面,也可以插在链表的尾部,但是为了方便,需要用一个指针始终指向链表的尾节点
48         t->next = p->next;
49         p->next = t;
50     }
51     Solution s;
52     r = s.FindKthToTail(p, 999);
53     cout << r->val << endl;
54 
55     system("pause");
56     return 0;
57 }
View Code

参考代码

https://blog.csdn.net/yummy_alice/article/details/81358894 

https://blog.csdn.net/u013686654/article/details/73827816

猜你喜欢

转载自www.cnblogs.com/wxwhnu/p/11410025.html