1.给定一个整形数组,是否能找出其中的两个数使得其和为某个指定的值?
- 示例: 输入数组为{1, 5, 7, 3}, 指定值为10, 则我们可以从中找出两个数3和7, 和等于10。
暴力穷举: 时间复杂度 O(n^2)
def hasSum(array, target_number):
len_array = len(array)
for i in range(0, len_array - 1):
for j in range(len_array - 1, i, -1):
while array[i] + array[j] == target_number:
return (1, array[i], array[j])
return (0, None, None)
if __name__ == '__main__':
array = [1, 5, 7, 3, 2]
target_number = 5
result, a, b = hasSum(array, target_number)
if result == 1:
print('YES, %d + %d = %d' % (a, b, target_number))
else:
print('NO')
优化算法:
2.股票买卖,给定一个数组,第i个元素代表第i天的股价。假设最多允许进行1次买卖,求可能的最大利润是多少?
- 示例: 输入price = [12, 15, 14, 8, 11, 10, 12], 则输出最大利润是4。
暴力穷举:
def maxProfit(price):
all_num = []
len_price = len(price)
for i in range(len_price):
for j in range(i + 1, len_price):
num = price[j] - price[i]
all_num.append(num)
return max(all_num)
if __name__ == '__main__':
price = [12, 15, 14, 8, 11, 10, 12]
result = maxProfit(price)
print(result)
算法优化:
'''
解题思路
到最后交易结束时,一共会有3种状态:
dp0:一直不买
dp1:只买了一次
dp2:买了一次,卖了一次
初始化3种状态:
dp0 = 0
dp1 = - prices[0]
dp2 = float("-inf")
因为第一天不可能会有dp2状态,因此将dp2置为负无穷
(Java中置为int的下边界)
对3种状态进行状态转移:
dp0 = 0
一直为0
dp1 = max(dp1, dp0 - prices[i])
前一天也是dp1状态,或者前一天是dp0状态,今天买入一笔变成dp1状态
dp2 = max(dp2, dp1 + prices[i])
前一天也是dp2状态,或者前一天是dp1状态,今天卖出一笔变成dp2状态
最后一定是手里没有股票赚的钱最多,因此返回的是dp0,dp2的最大值
'''
def maxProfit(prices) -> int:
dp0 = 0 # 一直不买
dp1 = - prices[0] # 只买了一次
dp2 = float('-inf') # 买了一次,卖了一次
for i in range(1, len(prices)):
dp1 = max(dp1, dp0 - prices[i])
dp2 = max(dp2, dp1 + prices[i])
return max(dp0, dp2)
'''
复杂度分析
时间复杂度:O(n)O(n)
空间复杂度:O(1)O(1)
'''
3.给定两个数组表示的整数, 比如 x=1234=[1, 2, 3, 4], y=2410=[2, 4, 1, 0], 返回第一个整数重组后的值最接近第二个整数, 并且大于第二个整数。假设两个整数的数组大小相同,并且肯定能找出符合条件的数。
- 示例: 输入[1, 2, 3, 4]和[2, 4, 1, 0], 返回[2, 4, 1, 3] or ‘2413’
# 函数调用格式如下
def getclosenumber(x, y):
# x 重组后, 大于 y
y = int(''.join([str(a) for a in y]))
x = [str(b) for b in sorted(x)]
n = len(x)
used = [] # 用来存放已经用过的数字
path = [] # 用来存放符合条件的结果
# 现排序x, 然后使用回溯算法暴力求解
def backtrack():
if len(path) == n and int(''.join(used)) > y:
# print(int(''.join(used)))
return int(''.join(used))
for i in range(0, n):
if x[i] in used:
continue
path.append(x[i])
used.append(x[i])
ret = backtrack()
if ret:
return ret
else:
used.pop()
path.pop()
return backtrack()
def main():
x = [1, 2, 3, 4]
y = [2, 4, 1, 0]
res = getclosenumber(x, y)
print("res=%s" % res)
if __name__ == '__main__':
main()
4.快速排序
def quick_sort(list1, start, end):
"""快速排序"""
# 递归的结束条件
if start >= end:
return
# 界限值
mid = list1[start]
# 左右游标
left = start
right = end
while left < right:
# 从右边开始找寻小于mid的值 归类到左边
while list1[right] >= mid and left < right:
right -= 1
list1[left] = list1[right]
# 从左边开始找寻大于mid的值 归类到右边
while list1[left] < mid and left < right:
left += 1
list1[right] = list1[left]
# 循环一旦结束了 证明找到了mid应该在的位置
list1[left] = mid
# 递归操作
quick_sort(list1, start, left - 1)
quick_sort(list1, right + 1, end)
if __name__ == '__main__':
array1 = [3, 6, 9, 2, 4, 8, 15, 17]
quick_sort(array1, 0, len(array1) - 1)
print(array1)
5.蛙跳,给出一维非负元素的数组,每个元素代表该元素位置能够跳的最远距离。假设初始位置在第一个元素,请根据输入数组判断是否能跳到数组的末尾。
-
示例:
- 输入数组 A = [2, 1, 3, 1, 1], 输出True
- 输入数组 A = [3, 2, 1, 0, 1], 输出False
def canJump(nums):
max_i = 0 # 初始化当前能到达最远的位置
for i, jump in enumerate(nums): # i为当前位置,jump是当前位置的跳数
if max_i >= i and i + jump > max_i: # 如果当前位置能到达,并且当前位置+跳数>最远位置
max_i = i + jump # 更新最远能到达位置
return max_i >= i
if __name__ == '__main__':
a = [2, 1, 3, 1, 1]
b = [3, 2, 1, 0, 1]
res = canJump(a)
print(res)
6. 给出一个单向链表的头指针, 如果链表有环, 则返回环的长度, 否则返回0.
- 示例: head -> 3 -> 8 -> 7 -> 1 -> 2 -> 3 -> 4 -> 5 -> 1, 则返回5
class ListNode(object):
def __init__(self, value=0):
self.value = value
self.next_node = None
def lengOfCircle(node):
# 如果头节点为为空则返回0
if not node:
return 0
# 计数器
count = 1
# 定义头为node
head = node
# 下一个就是node的下一个
next = node.next_node
# 当next存在
while next:
# 如果next不是头
if next != head:
# 计数器+1
count += 1
# 下一个就是node的下一个
next = next.next_node
else:
# 返回长度
return count
return 0
# 下面完成构造链表的代码
# 3 -> 8 -> 7 -> 1 -> 2 -> 3 -> 4 -> 5 -> 1
def main():
head = ListNode(3)
one = ListNode(8)
two = ListNode(7)
three = ListNode(1)
four = ListNode(2)
head.next_node = one
one.next_node = two
two.next_node = three
three.next_node = four
four.next_node = head
# 调用你编写的代码函数, 唯一的参数是头指针head
res = lengOfCircle(head)
print(res)
if __name__ == '__main__':
main()