zoukankan      html  css  js  c++  java
  • 【面试题15】链表中倒数第k个结点

    【题目描述】

    输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第一个结点。

    例如,一个链表有6个结点,从头结点开始他们的值依次是1,2,3,4,5,6。

    这个链表的都属第三个结点是值为4的结点。

    【解决方案】

    方法:设置两个指针p1,p2。p1先走k个结点,然后p2开始和p1同步走,p1走到尾结点的时候,p2所指的结点即为倒数第k个结点。

    考虑特殊情况:

    1. 链表为空;

    2. 链表结点数量小于k;

    3. 输入k小于等于0的情况,会影响程序的鲁棒性(具体看代码);

    我的代码实现,仅供参考:

     1         public static ListNode FindKthNode(ListNode head, int k)
     2         {
     3             if (head == null || k<=0)
     4             {
     5                 return null;
     6             }
     7             
     8             ListNode p1 = head , p2 = head;
     9 
    10             //根据题意链表尾节点为倒数第一个
    11             //故i < k-1,所以k > 0
    12             for (int i = 0; i < k-1; i++)
    13             {
    14                 //处理链表结点数量小于k的情况
    15                 if (p1.Next == null)
    16                 {
    17                     return null;
    18                 }
    19                 else
    20                 { 
    21                     p1 = p1.Next;
    22                 }
    23             }
    24 
    25             while (p1.Next != null)
    26             {
    27                 p1 = p1.Next;
    28                 p2 = p2.Next;
    29             }
    30 
    31             return p2;
    32         }

    【相关题目】

    1. 求链表的中间结点。如果链表中结点总数为奇数,则返回中间结点,如果为偶数,则返回中间结点两个中的任意一个。

    方法:设置两个指针p1,p2。同时从head开始走,p1每次走两步,p2每次走一步,p1到达尾节点时,p2所指结点即为中间结点。

    我的代码实现,仅供参考:

     1         public static ListNode FindMidhNode(ListNode head)
     2         {
     3             if (head == null)
     4             {
     5                 return null;
     6             }
     7 
     8             ListNode p1 = head, p2 = head;
     9 
    10             while (p1.Next!=null && p1.Next.Next != null)
    11             {
    12                 p1 = p1.Next.Next;
    13                 p2 = p2.Next;
    14             }
    15 
    16             return p2;
    17         }

    2. 判断一个单向链表是否形成了环形结构。

    方法:设置两个指针p1,p2。同时出发,p1每次走两步,p2每次走一步,如果p1追上p2,和p2所指结点相同,则证明链表中存在环形结构。

    我的代码实现,仅供参考:

     1         public static bool HasCircle(ListNode head)
     2         {
     3             if (head == null || head.Next == null)
     4             {
     5                 return false;
     6             }
     7 
     8             ListNode p1 = head.Next, p2 = head;
     9             bool hasCircle = false;
    10 
    11             while (p1.Next != null && p1.Next.Next != null)
    12             {
    13                 if (p1 == p2)
    14                 {
    15                     hasCircle = true;
    16                     break;
    17                 }
    18                 p1 = p1.Next.Next;
    19                 p2 = p2.Next;
    20             }
    21 
    22             return hasCircle;
    23         }

     【举一反三】

    当我们用一个指针遍历链表不能解决问题的时候,可以尝试用两个指针来遍历链表。可以让其中一个指针遍历的速度快一些,或者让它先在链表上走若干步。

  • 相关阅读:
    话说地址栏的URL的最大长度
    程序员,我拿什么来拯救自己
    把女友升级为老婆的时候发生的BUG
    一个精典asp程序引发的错误引起的思考
    [转]提高 Web Service 数据传输效率的基本方法
    整理发布html的select控件实用js操作
    asp.net简单实现导出excel报表
    c#简单实现生成csv文件
    利用sql server直接创建日历
    jQuery学习笔记:效果
  • 原文地址:https://www.cnblogs.com/HuoAA/p/4803165.html
Copyright © 2011-2022 走看看