zoukankan      html  css  js  c++  java
  • python经典算法面试题1.5:如何找出单链表中的倒数第K个元素

    本题目摘自《Python程序员面试算法宝典》,我会每天做一道这本书上的题目,并分享出来,统一放在我博客内,收集在一个分类中。

    【微软笔试题】

    难度系数:⭐⭐⭐
    考察频率:⭐⭐⭐⭐⭐

    题目描述:

    找出单链表中的倒数第k个元素,例如给定单链表:1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7,则单链表的倒数第3个元素为5.

    方法一:顺序遍历法
    这种方法需要对单链表进行两次遍历,第一次遍历得到单链表的长度,这样我们在第二次遍历过程中就知道了什么时候找到了我们需要的那个元素了。

    方法二:快慢指针法
    由于单链表只能从头到尾巴依次访问链表的各个结点,因此如果我们要找链表的倒数第k个元素,也只能从头到尾巴遍历查找,设置两个指针,让其中一个指针比令一个指针先走k步(如果第k个元素存在的话),然后两个指针同时向后走,直到快指针走到最后一个元素,这时候慢指针所指向的位置就是要找的元素了。

    两个方法的代码如下:

    class Node:  # 结点类
        def __init__(self, data):
            self.data = data
            self.next = None
    
    class SingleLinkList:  # 单链表类
        def __init__(self):
            self.head = None
            self.tail = None
    
        def append(self, x):  # 单链表尾部追加方法
            if self.head is None:
                self.head = self.tail = Node(x)
            else:
                self.tail.next = Node(x)
                self.tail = self.tail.next
    
    # 创建链表
    test_link = SingleLinkList()
    for i in range(1, 8):
        test_link.append(i)
        
    # 打印链表看一下
    p = test_link.head
    print("链表:", end="	")
    while p is not None:
        print(p.data, end="	")
        p = p.next
    print()
    
    # 方法一 顺序遍历法
    def find_it(link: SingleLinkList, k):
        # 第一步获取长度
        i = 0
        p = link.head
        while p is not None:  # 循环完成后 i就是链表的长度
            i += 1
            p = p.next
        if i < k:
            return None
    
        j = 0
        p = link.head
        while i - j > k:  # 循环完成后 p就是倒数第三个结点
            p = p.next
            j += 1
    
        return p.data
    
    # 测试方法一
    t = test_link
    k = 5
    print(f"倒数第{k}个元素是:", find_it(t, k), "(顺序遍历法)")
    
    
    # 方法二 快慢指针法
    def find_it(link: SingleLinkList, k):
        slow = link.head  # slow指向第一个元素
        j = 1
        p = link.head
        while p is not None:  # 如果链表的元素个数少于k, return None
            p = p.next
            j += 1
            if j >= k:
                break
        else:
            return None
        fast = p  # fast指向第k个元素
        while fast.next is not None:  # 循环结束之后fast指向最后一个元素,slow指向倒数第k个元素
            slow = slow.next
            fast = fast.next
        return slow.data
    
    
    # 测试方法二
    t = test_link
    k = 5
    print(f"倒数第{k}个元素是:", find_it(t, k), "(快慢指针法)")
    
    

    两个方法的时间复杂度都是O(n),不同在于方法一最坏可能要遍历两遍,方法二只需要遍历一遍。

  • 相关阅读:
    什么是ORM
    ORM优缺点
    Azure 中快速搭建 FTPS 服务
    连接到 Azure 上的 SQL Server 虚拟机(经典部署)
    在 Azure 虚拟机中配置 Always On 可用性组(经典)
    SQL Server 2014 虚拟机的自动备份 (Resource Manager)
    Azure 虚拟机上的 SQL Server 常见问题
    排查在 Azure 中新建 Windows 虚拟机时遇到的经典部署问题
    上传通用化 VHD 并使用它在 Azure 中创建新 VM
    排查在 Azure 中新建 Windows VM 时遇到的部署问题
  • 原文地址:https://www.cnblogs.com/duanming/p/11830262.html
Copyright © 2011-2022 走看看