和左神学习刷题
目录
一、《程序员代码面试指南》Python实现
二、思路总结
三、B站地址
四、相关书籍
一、《程序员代码面试指南》Python实现
博客地址:https://blog.csdn.net/qq_34342154/article/details/77918297
代码地址:https://github.com/Liwenbin1996/Data_Structures_and_Algorithms
二、思路总结
学习其刷题习惯和思考思路
1. 水王数问题
1 # coding:utf-8 2 """ 3 输入:一个列表,如果列表中有一个数出现的频率超过总个数的一半,则称其为水王 4 输出:水王数,如果没有则返回-1 5 要求:时间复杂度O(n),空间复杂度O(1) 6 例如:[3,2,1,2,3,3,3,4,3,3],返回 3 7 思路:每次从列表中取两个不同的数删掉, 8 1)如果没有数剩下,则没有水王,返回-1 9 2)最后留下来一个数,判断其在列表中出现的频率是否超过总数一半,是则为水王,否则没有水王,返回-1 10 引申:总统选举问题,每次两张选票对比是否相同,候选人票数超过一半则选举有效,再通过比对频率找到总统 11 """ 12 class Solution : 13 def findShuiKing(self, alist) : 14 if len(alist) == 0 : 15 return -1 16 #候选人 17 candicate = 0 18 #血量,血量为0则无候选人,血量大于0则有候选人 19 HP = 0 20 for i in range(len(alist)) : 21 #如果无候选人,则把当前数立为候选人,HP赋值为1 22 if HP == 0 : 23 candicate = alist[i] 24 HP = 1 25 #如果有候选人且候选人和当前数不等,则HP -1 26 elif alist[i] != candicate : 27 HP -= 1 28 #如果有候选人且候选人和当前数相等,则HP +1 29 else : 30 HP += 1 31 #如果最终的血量为0,则没有候选人 32 if HP == 0 : 33 return -1 34 #如果最终有候选人,判断候选人出现的频率,超过一半则就是水王,否则不存在水王 35 if alist.count(candicate) > len(alist) // 2 : 36 return candicate 37 else : 38 return -1 39 40 s = Solution() 41 alist = [3,2,1,2,3,3,3,4,3,3] 42 res = s.findShuiKing(alist) 43 print(res)
2. 二分法相关
四种类型问题可以用二分法:
1)在一个有序数组中,找某个数是否存在
2)在一个有序数组中,找>=某个数最左侧的位置
3)在一个有序数组中,找<=某个数最右侧的位置
4)局部最小值问题
案例一
1 # coding:utf-8 2 import random 3 4 """ 5 类型2 6 """ 7 8 class Solution : 9 10 def findMinNum(self, alist, num ): 11 left = alist[0] 12 right = alist[-1] 13 # 最终需要返回的值,没有则为-1 14 target = -1 15 while left <= right : 16 mid = left + (right - left) // 2 17 mid2 = (left + right) // 2 18 if alist[mid] >= num : 19 #此时满足了 >=num 条件,将其赋予候选人target 20 target = alist[mid] 21 right = mid - 1 22 else : 23 left = mid + 1 24 25 return target 26 27 #此处为了创造对数器 28 def random_list(self, start, stop, length): 29 if length >= 0: 30 length = int(length) 31 start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start)) 32 random_list = [] 33 for i in range(length): 34 random_list.append(random.randint(start, stop)) 35 return random_list 36 37 38 s = Solution() 39 for i in range(10) : 40 rand_list = s.random_list(1,20,15) 41 alist = sorted(rand_list) 42 num = random.randint(1,10) 43 res = s.findMinNum(alist, num) 44 print(num,alist,res)
案例二
1 # coding:utf-8 2 import random 3 4 """ 5 类型3 6 """ 7 8 9 class Solution : 10 11 def findMaxNum(self, alist, num ): 12 left = 0 13 right = len(alist) - 1 14 # 最终需要返回的值,没有则为-1 15 target = -1 16 while left <= right : 17 mid = left + (right - left) // 2 18 if alist[mid] <= num : 19 #此时满足了 <=num 条件,将其赋予候选人target 20 target = alist[mid] 21 left = mid + 1 22 else : 23 right = mid - 1 24 25 return target 26 27 #此处为了创造对数器 28 def random_list(self, start, stop, length): 29 if length >= 0: 30 length = int(length) 31 start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start)) 32 random_list = [] 33 for i in range(length): 34 random_list.append(random.randint(start, stop)) 35 return random_list 36 37 38 s = Solution() 39 for i in range(10) : 40 rand_list = s.random_list(1,20,15) 41 alist = sorted(rand_list) 42 num = random.randint(1,10) 43 res = s.findMaxNum(alist, num) 44 print(num,alist,res)
案例三
1 # coding:utf-8 2 import random 3 4 """ 5 类型4 局部最小,即找到无序列表中的极小值 6 1.极小值的左边为空,右边比它大 7 2.极小值的右边为空,左边比它大 8 3.极小值的左右都比它大 9 """ 10 class Solution : 11 12 def findLessIndex(self, alist): 13 if len(alist) == 0 : 14 return -1 15 #一个值和左边界情况 16 if len(alist) == 1 or alist[0] < alist[1] : 17 return alist[0] 18 #右边界情况 19 if alist[-2] > alist[-1] : 20 return alist[-1] 21 #去除边界,因为边界必须是从大到小的,否则不存在极小值 22 left = 1 23 right = len(alist) - 2 24 mid = 0 25 while left < right : 26 mid = left + (right - left) // 2 27 print(mid, alist[mid - 1], alist[mid + 1]) 28 if alist[mid] > alist[mid - 1] : 29 right = mid - 1 30 elif alist[mid] > alist[mid + 1]: 31 left = mid + 1 32 else : 33 return mid 34 35 return left 36 37 #此处为了创造对数器 38 def random_list(self, start, stop, length): 39 if length >= 0: 40 length = int(length) 41 start, stop = (int(start), int(stop)) if start <= stop else (int(stop), int(start)) 42 random_list = [] 43 for i in range(length): 44 random_list.append(random.randint(start, stop)) 45 return random_list 46 47 48 s = Solution() 49 for i in range(10) : 50 rand_list = s.random_list(1,20,15) 51 res = s.findLessIndex(rand_list) 52 print(rand_list,res)
3. 打表找规律
1 # coding:utf-8 2 """ 3 1、输入类型简单,只有一个参数 4 2、要求返回值类型也简单,只有一个值 5 3、用暴力解法,把输入参数的返回值打印出来看看,优化code 6 例如: 7 定义一种数,可以表示成若干(数量大于1)连续正整数和的数 8 eg: 9 5 = 2 + 3,5就是这样的数 10 12 = 3 + 4 + 5,12就是这样的数 11 1 不是这样的数 12 2 也不是 13 输入:N 14 返回:是否可以表示成若干个连续正数和的数 15 """ 16 class Solution : 17 # 暴力解 18 def findNum(self, N): 19 for i in range(1, N) : 20 sum = i 21 for j in range(i + 1, N) : 22 if sum + j == N : 23 return True 24 if sum + j > N : 25 break 26 sum += j 27 return False 28 # 通过打表找规律,发现N是2的M次幂时,这个数不满足要求,其他符合(1-2单独求解) 29 def findNum2(self, N): 30 if N <= 2 : 31 return False 32 # 位运算 33 return N & (N - 1) != 0 34 35 36 s = Solution() 37 for k in range(100) : 38 res = s.findNum2(k) 39 print(k,res)
三、B站地址
https://www.bilibili.com/video/BV1to4y1D7ka?p=2
四、相关书籍
《程序员代码面试指南》

浙公网安备 33010602011771号