第一题
二维数组中的查找
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]
给定 target = 5,返回 true。
给定 target = 20,返回 false。
中等难度的题,难是难在思路,想到从左下角开始计算,副对角线上下分开,这题就可以做出来了,做一道会一类,我还去翻阅了BST相关资料,虽然感觉这里用到的不多,但是也帮助我复习了一下二叉搜索树的相关知识。
i = len(matrix)-1
j = 0
while i >= 0 and j < len(matrix[0]) :
if matrix[i][j] < target: j += 1
elif matrix[i][j] > target: i -= 1
else: return True
return False
第二题
旋转数组的最小数字
输入:numbers = [3,4,5,1,2]
输出:1
利用二分查找 找旋转点,旋转点后的第一个数就是要找的最小值。
# return min(numbers)
i = 0
j = len(numbers)-1
while i < j:
m = (i+j)//2
if numbers[m] > numbers[j]:
i = m + 1
elif numbers[m] < numbers[j]:
j = m
else:
j -= 1 # 放弃二分查找,因为剩余数据很少且重复, return min(numbers[i:j])
return numbers[i] #此时i=j,所以返回哪个都一样
关于返回值
并不是每一次,每一种题型,i 和 j 最后的值都是一样的,如果遇到不确定的情况,多数情况下盲选首选返回 i 。这个可以看解题思路 或是 循环条件,像这道题,循环条件是i > j,就可以一直循环,而i和j的初始值 初始情况是i > j ,所以循环的终止条件就应该是 i = j,由此可以断定,这道题的i 和 j 最后在返回时,值是一样的。
第三题
第一个只出现一次的字符
输入:s = “abaccdeff”
输出:‘b’
我写的:
# 考虑特殊情况
dic = {}
for i in s:
dic[i] = 0 #创建空间
for i in s:
dic[i] += 1 #出现就累加
if dic[i] == 1: #第一次出现 就返回 有问题
return i
缺陷:
没有办法得到正确答案
类似的方法在第四天的第二题也用到了,“统计一个数字在排序数组中出现的次数。”
最后用二分法做的这道题,“排序”和“二分”要绑定在一起。
大佬版的进阶写法是把重复的部分封装成一个helper的函数。
大佬写的:
dic = {}
for c in s:
dic[c] = not c in dic
for c in s:
if dic[c]: return c
return ' ' # 特殊情况
not c in dic 返回一个布尔值,表示:
c in dic 为判断字典中是否含有键 c
c in dic 是从键的角度考虑的
可以理解为,在第一次加入是,为Ture;之后无论加入多少次,都为False。
相当于构建了一个 s[i], True/False 的键值对
s = “abbb”
a, True
b, True
b, False
b, False
思想一样的,但技术不过关



