和左神学习刷题

目录

一、《程序员代码面试指南》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

 

 

四、相关书籍

《程序员代码面试指南》

 

posted @ 2021-07-25 14:21  舍得先森  阅读(159)  评论(0)    收藏  举报