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

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

思路:由于单项链表不能回头,我思考了两种方法

方法一:先遍历链表,算出链表节点数count,第二次直接遍历到第count-k个节点。但是要注意,可能链表结点数cout小于k,此时要返回NULL。这一条件要先判断。

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
    //   ListNode temp(0);
        int count=0;//count用于统计结点数量
        ListNode *temp = pListHead; 
        
        while (temp != NULL) //统计节点个数
        {
            ++count;
            temp = temp->next;
            
        }
        count -= k;
       // pListHead = temp;
		temp = pListHead;
    
        //注意:要判断要找的节点是否在范围内,如果在范围内,返回节点;如果不在,返回NULL
        if(count>=0)
        { 
            while (count--) //从前往后再次搜索
            {
                temp = temp->next;
            }
            return temp;
        }
        else
            return NULL;
        
    }
};

方法二

可以用两个指针,一个指针遍历到第k个结点的时候,第二个指针再走到第一个节点,然后两个指针的距离始终保持k-1,这样,当第一个指针的next==NULL,也就是走到最后一个节点的时候,第二个指针对应的位置,就是倒数第k个结点。

这样的好处是能够节省一个循环,时间复杂度会相应降低。从Q(2N) 到Q(N)

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

代码如下:可以直接拷贝到IDE上编译运行


  //#include <stdio.h>
  #include <stdlib.h>
  #include <vector>
  #include <stack>
  #include <math.h>
  #include <iostream>
using namespace std;
struct ListNode {
	int val;
	struct ListNode *next;
	ListNode(int x) :
			val(x), next(NULL) {
	}
};
class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        ListNode *first = pListHead; //第一个指针first
        ListNode *second = pListHead; //第二个指针second
		int i;
		if(first == NULL)
			return NULL;

		for(i = 1; i <= k; i++){
		   if(first->next == NULL)
			   break;如果已经走到头了,就跳出,否则继续走
		   first =  first->next;
		}
		while(first->next != NULL){//如果第一个指针没有走到头,两个指针想跟着一起走,保持k-1的距离
		    first =  first->next;
			second = second->next;
		}
      return second;
        
    }
};



 int main()
 {
    struct ListNode* p = (struct ListNode*)malloc(sizeof(struct ListNode));

    struct ListNode* r = (struct ListNode*)malloc(sizeof(struct ListNode));
    p->val = 0;
    p->next = NULL;

    for(int i = 1000; i >= 1; i--){
     struct ListNode* t = (struct ListNode*)malloc(sizeof(struct ListNode));//注意,这个空间申请一定要放到for循环内部。
        t->val = i;//这种方法是插在头节点p前面,当然也可以插在后面,也可以插在链表的尾部,但是为了方便,需要用一个指针始终指向链表的尾节点
        t->next = p->next;
        p->next=t;
    }
     Solution s;
     r = s.FindKthToTail(p,1000);
     cout << r->val << endl;
     system("pause");
     return 0;
 }


  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值