力扣刷题记录——697. 数组的度、728. 自除数 、821. 字符的最短距离

简介: 力扣刷题记录——697. 数组的度、728. 自除数 、821. 字符的最短距离

697. 数组的度

题目描述

给定一个非空且只包含非负数的整数数组 nums,数组的 的定义是指数组里任一元素出现频数的最大值。

你的任务是在 nums 中找到与 nums 拥有相同大小的度的最短连续子数组,返回其长度。

示例 1:

输入:nums = [1,2,2,3,1]

输出:2

解释:

输入数组的度是 2 ,因为元素 1 和 2 的出现频数最大,均为 2 。

连续子数组里面拥有相同度的有如下所示:

[1, 2, 2, 3, 1], [1, 2, 2, 3], [2, 2, 3, 1], [1, 2, 2], [2, 2, 3], [2, 2]

最短连续子数组 [2, 2] 的长度为 2 ,所以返回 2 。


示例 2:

输入:nums = [1,2,2,3,1,4,2]

输出:6

解释:

数组的度是 3 ,因为元素 2 重复出现 3 次。

所以 [2,2,3,1,4,2] 是最短子数组,因此返回 6 。

解题思路

这个题目的难点在于如果出现多个次数相同的元素,到底哪一个是最优解。首先给自己提个醒,如果涉及到列表中元素需要数个数,那么一定要先用set去除重复项,要不然很容易报超时错误!主要是用字典将元素及其属性相关联,根据值查找键所用的方法为[k for (k,v) in sic.items() if v == value],这样可以将所有最高项生成一个列表,然后遍历这个列表中的元素,index获取第一个出现的元素,将列表倒序,第一个出现的索引即为原列表该元素最后一次出现的索引。将这两个作差,最小值即为待求元素。最后就很简单了,做一个列表切割,返回最终结果就可以了。

解题代码

1. def findShortestSubArray(nums):
2. if len(nums) == 1:
3. return 1
4. # 问题的关键在于如果最高次出现了多项,怎么确定哪一项才是真正的最优解
5.     num_dic = {}
6. # 元素作为键,出现次数作为值
7.     set_dic_1 = {}
8. for i in list(set(nums)):
9.         set_dic_1[i] = nums.index(i)
10. for i in list(set(nums)):
11.         num_dic[i] = nums.count(i)
12.     max_ci = max(list(num_dic.values()))
13.     max_list = [k for (k,v) in num_dic.items() if v == max_ci]
14.     temp = {}
15. for num in max_list:
16. for i in range(len(nums) - 1, 0, -1):
17. if nums[i] == num:
18.                 end = i
19.                 temp[end-set_dic_1[num]] = num
20. break
21.     max_num = temp[min(list(temp.keys()))]
22. 
23.     l_index = nums.index(max_num)
24.     r_index = 0
25. for i in range(len(nums)-1,0,-1):
26. if nums[i]== max_num:
27.             r_index = i
28. break
29. return len(nums[l_index:r_index+1])

728. 自除数

题目描述

自除数 是指可以被它包含的每一位数整除的数。

  • 例如,128 是一个 自除数 ,因为 128 % 1 == 0128 % 2 == 0128 % 8 == 0

自除数 不允许包含 0 。

给定两个整数 leftright ,返回一个列表,列表的元素是范围 [left, right] 内所有的 自除数

示例 1:

输入:left = 1, right = 22

输出:[1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 15, 22]


示例 2:

输入:left = 47, right = 85

输出:[48,55,66,77]

解题思路

这题的关键在找到每位数,用字符串切片的方式会方便很多,然后就是while循环,以及判断最后一个,一定要注意边界问题。将目标元素添加到目标列表中,最终返回目标列表。

解题代码

1. def selfDividingNumbers(left: int, right: int):
2.     result = []  #盛放结果的列表
3. for i in range(left,right+1):
4.         count = 0
5.         temp_str = str(i)
6. if "0" not in temp_str:
7. while count <= len(temp_str) - 1:
8. if i % int(temp_str[count]) != 0:
9. break
10. if count == len(temp_str)-1:
11.                     result.append(i)
12.                 count +=1
13. else:
14. pass
15. 
16. return result

821. 字符的最短距离

题目描述

给你一个字符串 s 和一个字符 c ,且 cs 中出现过的字符。

返回一个整数数组 answer ,其中 answer.length == s.lengthanswer[i]s 中从下标 i 到离它 最近 的字符 c距离

两个下标 ij 之间的 距离abs(i - j) ,其中 abs 是绝对值函数。

示例 1:

输入:s = "loveleetcode", c = "e"

输出:[3,2,1,0,1,0,0,1,2,2,1,0]

解释:字符 'e' 出现在下标 3、5、6 和 11 处(下标从 0 开始计数)。

距下标 0 最近的 'e' 出现在下标 3 ,所以距离为 abs(0 - 3) = 3 。

距下标 1 最近的 'e' 出现在下标 3 ,所以距离为 abs(1 - 3) = 2 。

对于下标 4 ,出现在下标 3 和下标 5 处的 'e' 都离它最近,但距离是一样的 abs(4 - 3) == abs(4 - 5) = 1 。

距下标 8 最近的 'e' 出现在下标 6 ,所以距离为 abs(8 - 6) = 2 。


示例 2:

输入:s = "aaab", c = "b"

输出:[3,2,1,0]

解题思路

这题可以从左到右遍历一遍再从右到左遍历一遍,如果i为c的话count就为0,否则count累加,将结果储存一下。两次遍历取最小值就可以了。注意开始的时候,如果s[0]就等于c的话,好办,直接开始遍历就可以了。如果不等于c要把开始到c第一次出现之间的count进行倒叙,再添加到列表中。从右到左列表需要[::-1]变为正序,最后遍历两个列表,取相应位置的最小值,添加到目标列表中,最终返回这个目标列表。

解题代码

1. def shortestToChar(s: str, c: str):
2. # 从左到右遍历一遍,再从右到左遍历一遍,比较对应位置,选择最小的最为最终结果
3.     l_r = []
4.     r_l = []
5.     temp_1 = []
6.     temp_2 = []
7.     result = []
8.     count = 0
9. if s[0]==c:
10. for i in s:
11. if i == c:
12.                 count = 0
13. else:
14.                 count += 1
15.             l_r.append(count)
16. else:
17. for i in s[:s.index(c):]:
18. if i == c:
19.                 count = 0
20. else:
21.                 count += 1
22.             temp_1.append(count)
23.         l_r.extend(temp_1[::-1])
24. for i in s[s.index(c)::]:
25. if i == c:
26.                 count = 0
27. else:
28.                 count += 1
29.             l_r.append(count)
30.     s = s[::-1]
31. 
32. if s[0] == c:
33. for i in s:
34. if i == c:
35.                 count = 0
36. else:
37.                 count += 1
38.             r_l.append(count)
39. else:
40. for i in s[:s.index(c):]:
41. if i == c:
42.                 count = 0
43. else:
44.                 count += 1
45.             temp_2.append(count)
46.         r_l.extend(temp_2[::-1])
47. for i in s[s.index(c)::]:
48. if i == c:
49.                 count = 0
50. else:
51.                 count += 1
52.             r_l.append(count)
53.     r_l = r_l[::-1]   # 颠倒回来
54. for i in range(len(r_l)):
55.         result.append(min(r_l[i],l_r[i]))
56. 
57. return result

 


相关文章
|
3月前
|
Unix Shell Linux
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
本文提供了几个Linux shell脚本编程问题的解决方案,包括转置文件内容、统计词频、验证有效电话号码和提取文件的第十行,每个问题都给出了至少一种实现方法。
LeetCode刷题 Shell编程四则 | 194. 转置文件 192. 统计词频 193. 有效电话号码 195. 第十行
|
2月前
|
存储 算法
Leetcode第三题(无重复字符的最长子串)
这篇文章介绍了解决LeetCode第三题“无重复字符的最长子串”的算法,使用滑动窗口技术来找出给定字符串中最长的不含重复字符的子串,并提供了详细的代码实现和解释。
103 0
Leetcode第三题(无重复字符的最长子串)
|
2月前
|
算法
Leetcode 初级算法 --- 数组篇
Leetcode 初级算法 --- 数组篇
46 0
|
4月前
|
算法
LeetCode第53题最大子数组和
LeetCode第53题"最大子数组和"的解题方法,利用动态规划思想,通过一次遍历数组,维护到当前元素为止的最大子数组和,有效避免了复杂度更高的暴力解法。
LeetCode第53题最大子数组和
|
1月前
|
机器学习/深度学习 人工智能 自然语言处理
280页PDF,全方位评估OpenAI o1,Leetcode刷题准确率竟这么高
【10月更文挑战第24天】近年来,OpenAI的o1模型在大型语言模型(LLMs)中脱颖而出,展现出卓越的推理能力和知识整合能力。基于Transformer架构,o1模型采用了链式思维和强化学习等先进技术,显著提升了其在编程竞赛、医学影像报告生成、数学问题解决、自然语言推理和芯片设计等领域的表现。本文将全面评估o1模型的性能及其对AI研究和应用的潜在影响。
46 1
|
3月前
|
数据采集 负载均衡 安全
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
本文提供了多个多线程编程问题的解决方案,包括设计有限阻塞队列、多线程网页爬虫、红绿灯路口等,每个问题都给出了至少一种实现方法,涵盖了互斥锁、条件变量、信号量等线程同步机制的使用。
LeetCode刷题 多线程编程九则 | 1188. 设计有限阻塞队列 1242. 多线程网页爬虫 1279. 红绿灯路口
|
2月前
【LeetCode-每日一题】 删除排序数组中的重复项
【LeetCode-每日一题】 删除排序数组中的重复项
25 4
|
2月前
|
索引
Leetcode第三十三题(搜索旋转排序数组)
这篇文章介绍了解决LeetCode第33题“搜索旋转排序数组”的方法,该问题要求在旋转过的升序数组中找到给定目标值的索引,如果存在则返回索引,否则返回-1,文章提供了一个时间复杂度为O(logn)的二分搜索算法实现。
25 0
Leetcode第三十三题(搜索旋转排序数组)
|
2月前
|
算法 C++
Leetcode第53题(最大子数组和)
这篇文章介绍了LeetCode第53题“最大子数组和”的动态规划解法,提供了详细的状态转移方程和C++代码实现,并讨论了其他算法如贪心、分治、改进动态规划和分块累计法。
72 0
|
2月前
|
C++
【LeetCode 12】349.两个数组的交集
【LeetCode 12】349.两个数组的交集
22 0