2. 最大不重复字段判断
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
#因为是 ASCII码值,可以使用 256长度的 list 代表ascii码值
index_list = [-1 for i in range(256)]
#也可以直接使用字典
#index_map = {}
start = -1
maxLen = 0
str_len = len(s)
for j in range(str_len):
charac = s[j]
if index_list[ord(charac)] > start:
start = index_list[ord(charac)]
index_map[ord(charac)]=j
maxLen = max(maxLen,j-start)
return maxLen
class Solution(object):
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
#也可以直接使用字典
index_map = {}
start = -1
maxLen = 0
str_len = len(s)
for j in range(str_len):
charac = s[j]
if index_map.get(charac) > start:
start = index_map.get(charac)
index_map[charac]=j
maxLen = max(maxLen,j-start)
return maxLen
167. 两数之和
时间复杂度最大 是 O(2n) 最好成绩 36ms
首先遍历一次numbers 列表。 把每一个元素和它所对应的位置 用一个 字典存储 key :元素值 ,value:index+1。
遍历中用 和减去每一个数,如果小于0的结果舍去。 大于等于0的结果存入存入List 第一个元素差,第一个元素index+1。
然后遍历这个得到的结果List 取每一个值,跟字典的keys比较。看有没有,有的取出结果,排序后返回。
如果numbers 不是升序排列,双指针不适用。这个方法比较好。
class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
dict_num = {}
list_2 = []
for i in range(len(numbers)):
dict_num[numbers[i]] = i+1
diff = target - numbers[i]
if diff >= 0:
list_2.append([diff ,i+1])
for m in list_2:
if dict_num.get(m[0]) != None:
res = sorted([dict_num.get(m[0]),m[1]])
return res
改进版:
之前想可能在第一个循环判断 diff 是否在 dict_num 中如果 dict_num 还没有加入会漏掉结果。但是后来大神代码和自己根据思考得到,因为两个加数都在这个列表之内,漏掉了第一个加数后,第二个加数判断绝对不会漏掉。代码如下 时间复杂度为 O(n)
class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
dict_num = {}
list_2 = []
for i in range(len(numbers)):
diff = target - numbers[i]
if diff in dict_num:
return [dict_num[diff]+1 ,i+1]
dict_num[numbers[i]] = i
双指针
最大时间复杂度 O(n), 最优用时28ms 。利用了numbers 正排序规则。
从开始有一个指针 从头到尾, 末尾一个指针从尾向头进行搜索。 当末尾指针与头指针重合的时候说明整个数据列表遍历完成。所以需要末尾指针 index 大于 头指针index,当等于结果的时候返回 所在index+1。 如果两指针指向的结果大于目标值,说明两数和较大,减小较大的一个加数。 小了,说明两数和较小,增大较小的一个加数。
class Solution(object):
def twoSum(self, numbers, target):
"""
:type numbers: List[int]
:type target: int
:rtype: List[int]
"""
if len(numbers) < 2:
return False
index1 = 0
index2 = len(numbers) - 1
while index1 < index2:
if numbers[index1] + numbers[index2] == target:
return [index1+1,index2+1]
else:
if numbers[index1] + numbers[index2-1] >= target:
index2 -= 1
else:
index1 += 1
215. 快速选择、堆排序
利用堆排序进行计算。 计算方法
-
将数字转化为一个堆;
堆是具有以下两属性的二叉树:
(1)每个节点的值大于等于其子节点的值;
(2)树完全平衡,即最底层叶子节点都位于左侧(完全),且左右子树高度相差不超过1(平衡);堆也被称为优先队列,具有先进先出的特性,在堆底插入元素,在堆顶取出元素。
-
取出堆顶元素(最大元素),作为有序数数组末尾元素,并对二叉树进行调整使其满足堆的特性;
-
重复上一步骤,依次取出堆顶元素,并插入到有序数组中,上一插入元素之前的位置,直到堆空为止;
class Solution(object):
def moveDown(self,arr,first,last):
curIndex = first * 2 + 1
while curIndex <= last:
if curIndex < last and (arr[curIndex] < arr[curIndex +1]):
curIndex += 1
if arr[first] < arr[curIndex]:
arr[first],arr[curIndex] = arr[curIndex],arr[first]
first = curIndex
curIndex = curIndex * 2 + 1
else:
break
def buildHeap(self,arr):
i = len(arr)//2 -1
while i >=0:
self.moveDown(arr, i ,len(arr) -1)
i = i -1
def findKthLargest(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
self.buildHeap(nums)
first = 0
last = len(nums) - 1
k -= 1
while k >0:
nums[first],nums[last] = nums[last],nums[first]
last -=1
self.moveDown(nums, first, last)
k -=1
return nums[first]
347. 桶排序 前K个高频词
思路: 首先把 列表转化成 集合去重复。 然后加入字典为key , value是 0 。 遍历一次nums。得到各自个数。然后取 字典的 values 逆行排序, 然后根据头 k 个value,逆差找字典 找到key。返回结果。比较low ,速度很慢,但是绝对是原创。
class Solution(object):
def topKFrequent(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
num_set = set(nums)
num_list = list(num_set)
dict_1 = {}
dict_1 = dict_1.fromkeys(num_list,0)
for i in nums:
dict_1[i] = int(dict_1.get(i)) + 1
list_2 = sorted(list(dict_1.values()),reverse=True)
list_3 = []
for j in range(k):
n_key = list(dict_1.keys())[list(dict_1.values()).index(list_2[j])]
list_3.append(n_key)
dict_1.pop(n_key)
return list_3
75. 颜色分类
思路: 设置两个指针,头指针用于指向0 尾指针用于指向2。 然后从头开始对数组进行搜索,不用超过尾指针。因为尾指针会对2进行排列。 当遍历的索引 对应的数是0的时候,放到头指针对应位置,当前索引和头指针都加1。同理当前遍历的索引对应的数为2时候,放到尾指针对应位置,并且尾指针向前移动一格。
class Solution(object):
def sortColors(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
#设置指零的头指针
i = 0
#设置指2的尾指针
j = len(nums) - 1
#遍历 从头到尾每个位置都经过。
m = 0
#总体思路,遍历索引不能大于尾指针。由于我们知道 0,1,2 的值。就可以类似判断 为0的往头放
#为2的 往尾巴上面放。 索引直接增加的理念就行。
while m <= j:
if nums[m] == 0:
nums[m],nums[i] = nums[i],nums[m]
i +=1
m +=1
elif nums[m] == 2:
nums[m],nums[j] = nums[j],nums[m]
j -=1
else:
m +=1
455. 分发饼干
贪心算法的应用: 对孩子和 饼干都进行排序(ascend), 以饼干进行遍历。 孩子加一个头指针,如果饼干值不小于孩子值。数量加1,孩子头指针向后移动一格。 如果孩子遍历完成,或者饼干遍历完成结束循环。
class Solution(object):
def findContentChildren(self, g, s):
"""
:type g: List[int]
:type s: List[int]
:rtype: int
"""
g = sorted(g)
s = sorted(s)
z = 0
indx = 0
for ele in s:
if indx < len(g) and ele >= g[indx] :
z += 1
indx +=1
return z