Dongxing's Wiki Dongxing's Wiki
首页
  • 剑指 Offer
  • LeetCode
  • 算法与数据结构
  • Python 语言
  • Web 开发
  • Hive
  • Elastic Search
  • 机器学习
  • NLP
  • 检索技术
  • 数据分析
  • 经验笔记
  • Linux 配置
  • 博客进化记
  • 杂谈
GitHub (opens new window)
首页
  • 剑指 Offer
  • LeetCode
  • 算法与数据结构
  • Python 语言
  • Web 开发
  • Hive
  • Elastic Search
  • 机器学习
  • NLP
  • 检索技术
  • 数据分析
  • 经验笔记
  • Linux 配置
  • 博客进化记
  • 杂谈
GitHub (opens new window)
  • 剑指offer

    • 剑指 Offer - python 题解
    • 剑指Offer(1)
    • 剑指Offer(2)
    • 剑指Offer(3)
    • 剑指Offer(4)
    • 剑指Offer(5)
    • 剑指Offer(6)
      • 链表中倒数第k个节点
        • 问题
        • 思路
        • 代码
      • 反转链表
        • 问题
        • 分析
        • 代码
      • 合并两个排序的链表
        • 问题
        • 思路
      • 树的子结构
        • 题目
        • 思路
    • 剑指Offer(7)
    • 剑指Offer(8)
    • 剑指Offer(9)
    • 剑指Offer(10)
    • 剑指Offer(11)
    • 剑指Offer(12)
    • 剑指Offer(13)
    • 剑指Offer(14)
    • 剑指Offer(15)
  • 剑指Offer
  • 剑指offer
anthony
2021-04-05
目录

剑指Offer(6)

更新:此题解 markdown 源文件已放到 Github https://github.com/bytetopia/offer-coding-interviews-python (opens new window),欢迎前去给个小星星鸭!


# 链表中倒数第k个节点

# 问题

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

# 思路

1)先扫一遍链表,获得总个数n,然后从头走n-k+1次,就得到倒数第k个了。缺点是要扫两遍 2)两个指针从开头出发,第二个指针先往后走k-1步,然后两个指针同时往后走,当第二个到达末尾时,第一个指向的就是倒数第k个

需要注意 head为空、k小于或等于0时,k大于链表长度时的特殊情况 需留心不要写错边界条件

# 代码

class Solution:
    def FindKthToTail(self, head, k):
        if (not head) or k <= 0:
            return None
        count = 0
        pointer = head
        while(count < k and pointer):
            count += 1
            pointer = pointer.next
        if count < k:
            return None
        else:
            target = head
            while(pointer):
                target = target.next
                pointer = pointer.next
            return target
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 反转链表

# 问题

输入一个链表,反转链表后,输出链表的所有元素(函数返回头节点即可)。

# 分析

如下面所示,有三个指针,此时,让2的next指向1进行反转,然后指针2移动到3的位置,指针1移动到2的位置,指针3后移,继续进行反转,直到指针3指向为空时再进行最后一次反转。

需要特别注意的就是指针赋值的顺序有先后之分,不要弄丢了指针。

需注意代码鲁棒性,考虑到头节点指针为空、只有1个节点即头节点的两种特殊情况。

# 代码

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回ListNode
    def ReverseList(self, pHead):
        # 判断头节点为None或者只有头节点的特殊情况
        if not (pHead and pHead.next):
            return pHead
        a = pHead
        b = pHead.next
        # 需注意处理原来的头节点
        pHead.next = None
        while(b):
            c = b.next
            b.next = a
            a = b
            b = c
        return a
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 合并两个排序的链表

# 问题

输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。

# 思路

两个指针指向两个链表,比较当前两个数,把较小的连到结果链上,指针后移,直到其中某个链表走完,把另一链表余下部分连到结果链末尾即可。

需要注意处理特殊输入(空)的情况。

# -*- coding:utf-8 -*-
# class ListNode:
#     def __init__(self, x):
#         self.val = x
#         self.next = None
class Solution:
    # 返回合并后列表
    def Merge(self, pHead1, pHead2):
        # write code here
        h = ListNode(0)
        head = h
        p1, p2 = pHead1, pHead2
        while p1 and p2:
            if p1.val <= p2.val:
                h.next = p1 
                h = p1
                p1 = p1.next 
            else:
                h.next = p2
                h = p2
                p2 = p2.next 
        if p1:
            h.next = p1
        if p2:
            h.next = p2
        return head.next
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

注意由于是链表,所以最后将余下部分直接整个链上就行,不需要再去遍历余下的部分了 = =

# 树的子结构

# 题目

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

# 思路

首先遍历树1,找到树1中与树2根节点值相等的节点,说明可能就是子结构的根。 然后检查以此节点为根的树3,是否包含树2中的结构。特别注意是3包含2,因此应当遍历2,看2中的结构在3中是否都有,即使3比2多,若2的结构3都有的话,也是包含。

class Solution:
    def HasSubtree(self, pRoot1, pRoot2):   # 相当于这里做了一次递归的先序遍历,用来找p1中跟p2根结点相等的节点。
        result = False
        if pRoot1 and pRoot2:
            if pRoot1.val == pRoot2.val:
                result = self.check_structure(pRoot1, pRoot2)
            if not result:
                result = self.HasSubtree(pRoot1.left, pRoot2) # 需注意这里是 HasSubtree
            if not result:
                result = self.HasSubtree(pRoot1.right, pRoot2)
        return result
        
    def check_structure(self, root1, root2):  # 这里又是一种递归的先序遍历,用来判断两棵子树是否是root1包含了root2
        if not root2:
            return True
        if not root1:
            return False
        if root1.val != root2.val:
            return False
        left_check = self.check_structure(root1.left, root2.left)
        right_check = self.check_structure(root1.right, root2.right)
        return left_check and right_check
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
上次更新: 2022/11/11, 2:11:00
剑指Offer(5)
剑指Offer(7)

← 剑指Offer(5) 剑指Offer(7)→

Theme by Vdoing | Copyright © 2017-2023 anthony 京ICP备17072417-3
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式