剑指offer
1.不用加减乘除做加法:
# -*- coding:utf-8 -*-
# author= 'huang_wave'
class Solution(object):
def Add(self,num1, num2):
return sum([num1, num2])
if __name__ == '__main__':
su = Solution()
s = su.Add(5,6)
print(s)
2.丑数:
把只包含质因子2,3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但7、14不是,因为它们包含质因子7。 习惯上我们把1当做是第一个丑数。
# -*- coding:utf-8 -*-
# author = 'huangwave'
# 输出索引几个的丑数
class Solution(object):
def GetUglyNumber_Solution(self, index):
if index <= 0:
return 0
#习惯把1作为丑数
uglylist = [1]
twoidx = 0
threeidx = 0
fiveidx = 0
for i in range(index-1):
new = min(uglylist[twoidx]*2, uglylist[threeidx]*3, uglylist[fiveidx]*5)
uglylist.append(new)
if new%2 == 0:
twoidx += 1
if new%3 == 0:
threeidx += 1
if new%5 == 0:
fiveidx += 1
return uglylist[-1]
if __name__ == '__main__':
u = Solution()
print(u.GetUglyNumber_Solution(3))
3.两个链表的公共节点:
把只包含质因子2,3和5的数称作丑数(Ugly Number)。例如6、8都是丑数,但7、14不是,因为它们包含质因子7。 习惯上我们把1当做是第一个丑数。
分析:
首先要理解什么是公共节点,并不是两个节点的值相同就是公共节点。
而是在第一链表和第二链表中都存在一个节点,该节点往后的子链表在两个链表中是相同的。
假定 List1长度: a+n List2 长度:b+n, 且 a<b,
那么 p1 会先到链表尾部, 这时p2 走到 a+n位置,将p1换成List2头部,
接着p2再走b+n-(n+a) =b-a 步到链表尾部,这时p1也走到List2的b-a位置,
还差a步就到可能的第一个公共节点。将p2 换成 List1头部,p2走a步也到可能的第一个公共节点。
如果恰好p1==p2,那么p1就是第一个公共节点。 或者p1和p2一起走n步到达列表尾部,
二者没有公共节点,退出循环。 同理a>=b.时间复杂度O(n+a+b)
# -*- coding:utf-8 -*-
# author = 'huangwave'
# class ListNode(object):
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution(object):
def FindFirstCommonNode(self, pHead1, pHead2):
if not pHead1 or not pHead2:
return None
p1, p2 = pHead1, pHead2
while p1 != p2:
p1 = pHead2 if not p1 else p1.next
p2 = pHead1 if not p2 else p2.next
return p1
4.二维数组查找目标值:
算法思想:先用快排,将每一行进行排序,排完后进行查找。
# ------utf8------
# author = ‘黄wave’
# 二维数组查找
class Solution(object):
def quick_sort(self,data,low,high):
left = low
right = high
# 判断列表是否为空
if low >= high:
return
temp = data[left]
while left < right:
while left < right and data[right] >= temp:
right -= 1
data[left] = data[right]
while left <right and data[left] <= temp:
left += 1
data[right] = data[left]
data[left] = temp
self.quick_sort(data,low,left-1)
self.quick_sort(data,left+1,high)
return data
# 构建一维列表二分查找
def search_target(self,l,target):
high = len(l)-1
low = 0
if low == high:
if l[low] == target:
print("查到了!!!")
return low
while low < high:
mid = int((low+high)/ 2)
if l[mid]==target:
print("查到了!!!")
return mid
if l[mid] > target:
high = mid-1
else:
low = mid +1
return False
if __name__ == '__main__':
s = Solution()
sorted_l =[]
l = [[2,55,8,4,1,0],[2,3,8,55,-1,0],[-2,5,-8,4,1,0],[2,55,9,4,-5,0]]
for i in range(len(l)):
ss = s.quick_sort(l[i],0,len(l[i])-1)
sorted_l.append(ss)
target = int(input("请输入要查找的数值:"))
i = 0
while i < len(l):
if s.search_target(sorted_l[i], target):
print("在排序后的第 %d行 第 %d 个位置" % (i,s.search_target(sorted_l[i], target) + 1))
i += 1
输出:
请输入要查找的数值:8
查到了!!!
查到了!!!
在排序后的第 0行 第 5 个位置
查到了!!!
查到了!!!
在排序后的第 1行 第 5 个位置
5.二叉树的建立及前中后序遍历:
python是动态编程语言,没有指针,可以通过创建类来定义指针。
# ----utf8----
# author == 'huangwave'
class Node_tree(object):
def __init__(self,val):
self.value = val
self.left = None
self.right = None
def creat_tree(root,val):
newnode = Node_tree(val)
if root == None:
root = newnode
return root
else:
current = root
while current != None:
backup = current
if current.value > val:
current = current.left
else:
current = current.right
if backup.value > val:
backup.left = newnode
else:
backup.right = newnode
return root
# 前序遍历
def preorder(root):
ptr = root
if ptr != None:
print('[%2d]' %ptr.value,end="")
preorder(ptr.left)
preorder(ptr.right)
# 中序排序
def inorder(root):
ptr = root
if ptr != None:
inorder(ptr.left)
print('[%2d]' %ptr.value,end="")
inorder(ptr.right)
# 后序遍历
def postorder(root):
ptr = root
if ptr != None:
preorder(ptr.left)
preorder(ptr.right)
print('[%2d]' % ptr.value,end="")
a = [5,1,8,3,4,0,6,7]
root = None
for i in range(len(a)):
root = creat_tree(root,a[i])
inorder(root)
print()
preorder(root)
print()
postorder(root)