感觉要学,要看的东西太多了。但是这其中,算法也一定是核心中的核心,于是决定有时间就刷刷题,研究了下,个人觉得照题的类型来可能效果要好些,这样可能对于某一种的题型就上手更快。奔跑吧,少年~~
0~n-1中缺失的数字
题目描述
一个长度为n-1的递增排序数组中的所有数字都是唯一的,并且每个数字都在范围0~n-1之内。在范围0~n-1内的n个数字中有且只有一个数字不在该数组中,请找出这个数字
代码实现
# 预期: [0,1,2,3,4,5,6,7,9] >> 8; [0,1,3] >> 2
# 暴力法,创造遍历的条件
# 思路: 手动构造有序表,因为缺少一个值,所以要构造的是nums+1个数的值,然后和数据按照索引位置对比就行了
class Solution:
def missingNumber(self, nums):
base = [i for i in range(len(nums) + 1)]
for i in range(len(nums)):
if nums[i] != base[i]:
return base[i]
if base:
return base[-1]
# 二分法
# 思路: 通过画图可以分析出只有两种情况,
# 1.mid = (right + left) // 2,(索引大小和索引值相等则代表当前索引之前的数字是不缺失的,那么继续在索 引值后面的位置搜索即可)
# 2.nums[mid] > mid,则代表着缺少的值在当前索引的前面位置,所以往前面去找就行了
# 结果:最后返回边界值即可
class Solution:
def missingNumber(self, nums):
left, right = 0, len(nums)
while left < right:
mid = (right + left) // 2
if nums[mid] == mid:
left += 1
elif nums[mid] > mid:
right -= 1
return right
高度检查器
题目描述
给一个无序列表,那么同时假设也存在这么一列表,是这个无序列表的有序展示,那么把无序表和有序表的相同索引位置进行对比的话,有几个不一样(数据大小为1-100之间)
代码实现
# 预期: heights = [1, 1, 4, 2, 1, 3] >> 3
# 解释: 排序之后的数组为 [1, 1, 1, 2, 3, 4], 那么发现只有索引位置为0,1和3的位置一模一样,所以返回3,代表 3个位置放置的位置错误
# 方法一: 基于桶排序
class Solution:
def heightChecker(self, heights):
count = 0
# 因为假设数据大小为1-100,则生成101个桶,目的是让每个桶存放和索引值相同的数值,(比如1号桶存放数值 等于1的数据),并计算每个桶内数据的个数
baes_list = [0 for _ in range(101)]
for num in heights:
baes_list[num] += 1
# 将桶内不等于1的数据依次添加到列表中,那么这个就是无序表排序之后结果
ret = []
for index in range(len(baes_list)):
while baes_list[index] != 0:
ret.append(index)
baes_list[index] -= 1
# 对桶排序的结果和原有列表一一进行对比,不对应的位置则是需要调换的次数
for i in range(len(heights)):
if heights[i] != ret[i]:
count += 1
return count
# 方法二: 原理一样,简化了一些步骤
class Solution:
def heightChecker(self, heights: List[int]) -> int:
d = [0] * 101
ans = j = 0
for i in heights:
d[i] += 1
for i in range(1, 101):
while d[i]:
if heights[j] != i:
ans += 1
j += 1
d[i] -= 1
return ans
最长连续递增序列
题目描述
给定一个未经排序的整数数组,找到最长且连续的的递增序列,并返回该序列的长度
代码实现
# 预期: [1,3,5,4,7] >> 3 [2,2,2,2,2] >> 1 (相同值不算递增关系)
# 解释: 最长连续递增序列是 [1,3,5], 长度为3。尽管 [1,3,5,7] 也是升序的子序列, 但它不是连续的,因为5和7在 原数组里被4隔开。
# 方法
class Solution:
def findLengthOfLCIS(self, nums):
ret = []
start_index = 0
for i in range(len(nums) - 1):
# 统计直到相邻值中后一个值小于前一个值的数据个数,并添加到统计长度列表中
if nums[i + 1] <= nums[i]:
end_index = i + 1
ret.append(end_index - start_index)
# 保证开始统计的索引值一定是出现当前情况下才开始变化
start_index = i + 1
# 如果最后几个数字呈递增状态,那么从开始到最后都为递增状态,于是用总长度减去上一次索引开始的位置/或 者最后一个值小于倒数第二个值
ret.append(len(nums) - start_index)
print(ret)
return max(ret)
拼写单词
题目描述
给你一份『词汇表』(字符串数组) words 和一张『字母表』(字符串) chars。
假如你可以用 chars 中的『字母』(字符)拼写出 words 中的某个『单词』(字符串),那么我们就认为你掌握了这个单词。
注意:每次拼写(指拼写词汇表中的一个单词)时,chars 中的每个字母都只能用一次。
返回词汇表 words 中你掌握的所有单词的 长度之和
代码实现
# words = ["cat","bt","hat","tree"], chars = "atach" >> 6 可以形成字符串 "cat" 和 "hat",所以答案是 3 + 3 = 6
# words = ["hello","world","leetcode"], chars = "welldonehoneyr" >> 10 可以形成字符串 "hello" 和 "world",所以答案是 5 + 5 = 10
# 我的方法(原理一样的,只是官方用了标准库,我知道collections的那个方法,我合计万一不让用标准库呢,所以就用了字典推倒,但是就因为我用了字典推导性能竟然下降了一半,空间使用差不多)
# 思路:
# 1.一看到这题,我就觉得应该是哈希解决,所以第一步先转成了字典,键为字符,值为出现的次数
# 2.然后判断单词是否是charts_dic的子集就可以了,我这里用了个函数判断,个人觉得比较好理解
class Solution:
def countCharacters(self, words, chars):
count = 0
chars_dic = {chars[i]: chars.count(chars[i]) for i in range(len(chars))}
for word in words:
word_dic = {word[i]: word.count(word[i]) for i in range(len(word))}
if self.contrast_dic(chars_dic, word_dic):
count += len(word)
return count
@staticmethod
def contrast_dic(base_dic, contrast_dic):
for key in contrast_dic:
# 只要key不在基础表中或者对应的次数值大于基础表,那么就为False
if key not in base_dic or contrast_dic[key] > base_dic[key]:
return False
return True
# 官方解法
class Solution:
def countCharacters(self, words: List[str], chars: str) -> int:
chars_cnt = collections.Counter(chars)
ans = 0
for word in words:
word_cnt = collections.Counter(word)
for c in word_cnt:
if chars_cnt[c] < word_cnt[c]:
break
else:
ans += len(word)
return ans
将每个元素替换为右侧最大元素
题目描述
给你一个数组 arr
,请你将每个元素用它右边最大的元素替换,如果是最后一个元素,用 -1
替换。
完成所有替换操作后,请你返回这个数组。
代码实现
# 预期: arr = [17,18,5,4,6,1] >>> [18,6,6,6,1,-1]
# 好理解,但是性能不好
class Solution:
def replaceElements(self, arr):
# 每一次都从后边的列表中拿最大数据赋值就行了
for index in range(len(arr) - 1):
arr[index] = max(arr[index + 1:])
arr[-1] = -1
return arr
# debug打一遍就理解了
class Solution(object):
def replaceElements(self, arr):
"""
:type arr: List[int]
:rtype: List[int]
"""
#倒序比较即可,最后替换两端元素
rmax = arr[-1]
for i in range(len(arr)-1, 0, -1):
temp = arr[i]
arr[i] = rmax
rmax = max(rmax, temp)
arr[0] = rmax
arr[-1]= -1
return arr