【July程序员编程艺术】之链表追赶问题

一.求链表的第K个节点
问题描述:
输入一个单向链表,输出该链表中倒数第k个结点,
链表的倒数第0个结点为链表的尾指针。

我的解题思路:
相比于之前遇到的数组,字符串问题,链表是一种新的数据结构,链表问题的解题思路也与之前的问题有所不同。一般的无循环单链表的特点是:尾节点的next指针为NULL,只知道头结点。对于本题,我一开始想到的简单思路是这样的:首先建立一个hash表,然后从链表的头结点开始进行遍历,同时维护一个计数变量cnt。对于链表中的每个节点,都会把该节点的指针经过hash函数的映射结果作为key值,以cnt作为value值,存于hash表中。这样遍历完链表之后,即可得到从头结点到各个节点之间的节点数目以及链表长度。这样一来,hash表中value值为length(list)-k的节点即为我们所要寻找的节点。
这种算法的时间复杂度为O(N),但是空间复杂度也为O(N)。

博客中给出的算法是采用两个指针,利用两个指针一前一后逐步前移来解决问题。这样做就可以在维持时间复杂度的情况下,减小空间复杂度为O(1)。之前遇到过求两数和为定值的问题,问题中也用到了两个指针的思想,应当把这种双指针思路视为常用思想,遇到各种问题都可以尝试去利用一下看看效果。
程序很简单,直接复制july博客中的程序

struct ListNode
{
    char data;
    ListNode* next;
};
ListNode* head,*p,*q;
ListNode *pone,*ptwo;

//@heyaming, 第一节,求链表倒数第k个结点应该考虑k大于链表长度的case。
ListNode* fun(ListNode *head,int k)
{
 assert(k >= 0);
 pone = ptwo = head;
 for( ; k > 0 && ptwo != NULL; k--)
  ptwo=ptwo->next;
 if (k > 0) return NULL;

 while(ptwo!=NULL)
 {
  pone=pone->next;
  ptwo=ptwo->next;
 }
 return pone;
} 

二.判断两个链表是否相交
题目描述:给出两个单向链表的头指针,比如h1、h2,判断这两个链表是否相交。

我的解题思路:
1.使用hash表。判断两个链表是否相交,即判断两个链表是否有公共元素,hash表在这里又可以显示出其作用。先遍历h1,建立hash表,之后再对hash2的每个元素,判断其是否在hash表中、时间复杂度O(N+M),空间复杂度O(N)。
2.优化思路。链表不同于数组,如果两个链表有是相交的(即有公共节点),那么该节点后面的所有节点都会一模一样,我们可以利用这个特性进行优化。
对于无循环链表:直接判断尾节点是否完全相同
对于循环链表:判断一链表上俩指针相遇的那个节点,在不在另一条链表上。(因为两个循环链表不管在哪个节点相交,从这个节点出发就一定会进入环,也一定会碰到两指针相遇的那个节点)
具体的实现程序就不再细说,详见July博客。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值