【问题标题】:Cracking the Coding Interview, 6th Edition- Q: 2.2破解编码面试,第 6 版- Q: 2.2
【发布时间】:2015-09-08 21:54:13
【问题描述】:

问题是将第 k 个元素返回到单链表的最后一个元素。所有提出的解决方案都非常复杂,我不知道为什么我的解决方案无效。有人可以告诉我为什么吗?

public class CrackTheInterview {


    /**
     * @param args the command line arguments
     */

    public static Node kthToLast(Node n, int k) //pass in LinkedList's head node
    {
        int counter = 1;
        while (n.next != null)
        {
            n = n.next;


        }
        //at the end of the while loop, n equals the last node in the LinkedList
        while (counter != k)
        {
            n = n.previous;
            counter++;
        }
        //now node n is the kth node from the end

        return n;
    }
}

class Node
{
    Node next = null;
    Node previous = null;
    int data;

    public Node (int d)
    {
        this.data = d;
    }

}

【问题讨论】:

  • 除了答案中指出的问题之外,问题陈述似乎不完整,因为它没有指定如果列表少于k 节点会发生什么。您的代码也没有考虑到这种可能性。
  • 好吧,你的Node 类不遵守问题描述。问题表明您有一个singly-linked list,并且您的节点同时有一个previous 和一个next。我猜这就是solution is invalid 的意思?

标签: java algorithm linked-list


【解决方案1】:

单链表不会同时包含nextprevious。你有一个双向链表,这显然使这个问题更容易。

【讨论】:

    【解决方案2】:

    我没有那本书的副本,所以我不知道其中可能会找到哪些复杂的解决方案,但是以下两指解决方案对我来说似乎很简单,并且与您的解决方案没有什么不同从使用单链表:

    /* Returns the kth last node in the list starting at n.
     * If the list is empty (n == null) returns null.
     * If k is <= 1, returns the last node.
     * If k is >= the number of nodes in the list, returns the first node.
     */
    public static Node kthToLast(Node n, int k) {
        Node advance = n;
        while (--k > 0 && advance != null) {
            advance = advance.next;
        }
        /* Now advance is k nodes forward of n. Step both in parallel. */
        while (advance != null) {
            advance = advance.next;
            n = n.next;
        }
        return n;
    }
    

    【讨论】:

      【解决方案3】:

      书中第一个解决方案说:

      解决方案 #1:如果已知链表大小

      如果链表的大小已知,则倒数第 k 个元素是第 (length - k) 个元素。我们可以 只需遍历链表即可找到该元素。因为这个解决方案非常简单,我们几乎可以 确定这不是面试官的意图。

      但是我们可以很容易地通过一次找到链表的大小!所以修改OP的问题,请问下面的答案有什么问题?

      我们使用两个指针。用一个求链表的大小,用另一个走(size - k) 步。

      (在 Python 中实现)

      def kth_to_last(head, k):
          p1 = head
          p2 = head
          counter = 0
          while p1.nxt is not None:   # calculating the size of the linked list
              p1 = p1.nxt
              counter += 1
          for _ in range(counter - k):
              p2 = p2.nxt
          return p2.val
      

      【讨论】:

      • 正是我的想法,时间复杂度 O(n) 和空间 O(1),与建议的解决方案相同,对吧?而且更容易理解,看不出有什么问题。特别是如果书中建议的替代方法是递归方法,这在这里似乎有点过头了。
      猜你喜欢
      • 2015-12-06
      • 1970-01-01
      • 1970-01-01
      • 2015-12-12
      • 2017-08-31
      • 2012-09-24
      • 2018-11-21
      • 2013-09-05
      • 1970-01-01
      相关资源
      最近更新 更多