剑指offer题解 python_剑指offer 第三章 题16-26题解 Python版

代码完整性基础功能;

输入边界值;

错误处理;

题16:数值的整数次方此题不需要考虑大数问题,仅仅是计算整数次方,所以处理好特殊值就行了。

class Solution:

def Power(self, base, exponent):

"""计算base的exponent次方

Arguments:

base {int} -- 整数

exponent {int} -- 指数,可正可负

Returns:

int -- 结果

"""

if base == 0:

return 0

if base == 1:

return 1

abs_exponent = self.abs_exp(base, abs(exponent))

if exponent > 0:

return abs_exponent

else:

return 1 / abs_exponent

# 此处处理有个窍门,可以二分计算

def abs_exp(self, base, exponent):

if exponent == 0:

return 1

if exponent == 1:

return base

res = self.abs_exp(base, exponent >> 1)

res *= res

if exponent & 1 == 1:

res *= base

return res

题17:打印从1到最大的n位数此题其实是想考察大数的处理,在python中,大数的影响几乎不存在,所以可以直接写。但是使用数组或者字符串表示大数的方式还是值得学一学。

def print_1_to_n(n):

if n < 1:

return

i = 1

while len(str(i)) <= n:

print(i)

i += 1

print(' ')

题18:删除链表的节点

题19:正则表达式匹配这个题情况分析很复杂。因为*可以表示出现任意次,所以在pattern中出现*时,s的推进情况就很复杂,此时用递归获取结果是最容易想明白的。

以模式的第二个字符为判断标准,来构造递归,具体看代码。

class Solution:

# s, pattern都是字符串

def match(self, s, pattern):

if len(s) == 0 and len(pattern) == 0:

return True

# 如果s长度不为0,而pattern长度为0,这种情况不可能匹配成功

elif len(s) != 0 and len(pattern) == 0:

return False

# 如果s长度为0, 而pattern长度不为0,那么可能会有pattern为'(.*)*'的情况

elif len(s) == 0 and len(pattern) != 0:

# 如果pattern第二位为0, pattern推进两个

if len(pattern) > 1 and pattern[1] == '*':

return self.match(s, pattern[2:])

else:

return False

# 如果s和pattern长度都不为0

else:

# pattern第二位为*

if len(pattern) > 1 and pattern[1] == '*':

# 如果s[0] != pattern[0]

if s[0] != pattern[0] and pattern[0] != '.':

return self.match(s, pattern[2:])

# 如果s[0] == pattern[0], 那么有三种情况

# 1. s不变,pattern后移两步(pattern前两个字符等价于空)

# 2. s右移一个, pattern右移两个 (pattern前两个字符等价于一个字符)

# 3. s右移一个, pattern不右移 (pattern前两个字符等价于多个字符))

else:

return self.match(s, pattern[2:]) or \

self.match(s[1:], pattern[2:]) or \

self.match(s[1:], pattern)

# pattern第二位不是*

else:

# 比较第一位的情况

if s[0] == pattern[0] or pattern[0] == '.':

return self.match(s[1:], pattern[1:])

else:

return False

这个题是真的烦。。

题20:表示数值的字符串这个题并没有什么意思,找到所有可有可无的片段凑正则就行了。

import re

class Solution:

# s字符串

def isNumeric(self, s):

return True if re.match(r"^[\+\-]?[0-9]*(\.[0-9]*)?([eE][\+\-]?[0-9]+)?$", s) else False

题21:调整数组顺序使奇数位于偶数前面这个题可以借助荷兰国旗问题求解。

# -*- coding:utf-8 -*-

class Solution:

def reOrderArray(self, array):

if array is None or len(array) < 2:

return array

p1 = 0

p2 = len(array) - 1

while p1 < p2:

if self.is_even(array[p1]) and not self.is_even(array[p2]):

self.swap(array, p1, p2)

while not self.is_even(array[p1]):

p1 += 1

while self.is_even(array[p2]):

p2 -= 1

def is_even(self, item):

return item & 1 == 0

def swap(self, array, i, j):

array[i], array[j] = array[j], array[i]

如果要求保留原数组奇数间的顺序以及偶数间的顺序,借助了辅助数组的代码如下:

# -*- coding:utf-8 -*-

class Solution:

def is_even(self, item):

return item & 1 == 0

def reOrderArray(self, array):

if array is None or len(array) < 2:

return array

assi_array = []

for item in array:

if not self.is_even(item):

assi_array.append(item)

for item in array:

if self.is_even(item):

assi_array.append(item)

return assi_array

代码鲁棒性判断输入

容错性

题22:链表中倒数第k个节点

题目:

输入一个链表,输出该链表中倒数第k个节点。本题从1开始计数,即尾节点为倒数第1个节点。

# -*- coding:utf-8 -*-

class ListNode:

def __init__(self, x):

self.val = x

self.next = None

class Solution:

def FindKthToTail(self, head, k):

"""打印链表倒数第k个节点

Args:

head (ListNode): 链表头结点

k (int): 指定数字

Returns:

ListNode: 倒数第k个节点

"""

p_ahead = head

p_behind = head

while k > 0:

if p_ahead is None:

return None

p_ahead = p_ahead.next

k -= 1

while p_ahead is not None:

p_ahead = p_ahead.next

p_behind = p_behind.next

return p_behind

题23:链表中环的入口节点

题目:

如果一个链表中包含环,如何找出环的入口节点?

# -*- coding:utf-8 -*-

class ListNode:

def __init__(self, x):

self.val = x

self.next = None

class Solution:

def EntryNodeOfLoop(self, pHead):

"""找到链表中环的入口节点

Args:

pHead (ListNode): 链表头结点

Returns:

ListNode: 入口节点(如果没有返回None)

"""

if pHead is None or pHead.next is None:

return None

p1 = p2 = pHead

while p2.next is not None:

p2 = p2.next.next

p1 = p1.next

if p1 == p2:

first_met = p1

count = 1

while p1.next != first_met:

p1 = p1.next

count += 1

p1 = p2 = pHead

for i in range(count):

p1 = p1.next

while p1 != p2:

p1 = p1.next

p2 = p2.next

return p1

return None

题24:反转链表

题目:

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

# -*- coding:utf-8 -*-

class ListNode:

def __init__(self, x):

self.val = x

self.next = None

class Solution:

def ReverseList(self, pHead):

"""反转链表,返回反转后的头

Args:

pHead (ListNode): 链表头

Returns:

ListNode: 反转之后链表头

"""

if pHead is None or pHead.next is None:

return pHead

new_head = self.ReverseList(pHead.next)

pHead.next.next = pHead

pHead.next = None

return new_head

题25:合并两个排序的链表

题目:

输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。

# -*- coding:utf-8 -*-

class ListNode:

def __init__(self, x):

self.val = x

self.next = None

class Solution:

def Merge(self, pHead1, pHead2):

"""合并两个排序链表

"""

if pHead1 is None:

return pHead2

elif pHead2 is None:

return pHead1

p1, p2 = pHead1, pHead2

merge_head = None

if p1.val < p2.val:

merge_head = p1

merge_head.next = self.Merge(p1.next, p2)

else:

merge_head = p2

merge_head.next = self.Merge(p1, p2.next)

return merge_head

数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和教育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值