三、查找(I)
由于最近时间紧张,之后会补充每道题的思路。
1.leetcode35 搜索插入位置
题目:给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
你可以假设数组中无重复元素。
思路:二分查找
class Solution:
def searchInsert(self, nums: List[int], target: int) -> int:
if not nums:
return 0
if target<nums[0]:
return 0
elif target>nums[-1]:
return len(nums)
else:
l,r=0,len(nums)-1
while l<r:
mid=l+(r-l)//2
if nums[mid]==target:
return mid
elif nums[mid]<target:
l=mid+1
else:
r=mid-1
if nums[l]<target:
return l+1
else:
return l
2.leetcode202 快乐数
题目:编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」定义为:对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和,然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。如果 可以变为 1,那么这个数就是快乐数。
如果 n 是快乐数就返回 True ;不是,则返回 False 。
思路:
class Solution:
def isHappy(self, n: int) -> bool:
already = set()
while n != 1:
sum = 0
while n > 0:
# 取n的最后一位数
tmp = n % 10
sum += tmp ** 2
# 将n的最后一位截掉
n //= 10
# 如果求的和在过程中出现过
if sum in already:
return False
else:
already.add(sum)
n = sum
return True
3.leetcode205 同构字符串
题目:给定两个字符串 s 和 t,判断它们是否是同构的。如果 s 中的字符可以被替换得到 t ,那么这两个字符串是同构的。所有出现的字符都必须用另一个字符替换,同时保留字符的顺序。两个字符不能映射到同一个字符上,但字符可以映射自己本身。
思路:
class Solution:
def isIsomorphic(self, s: str, t: str) -> bool:
return list(map(s.index,s)) == list(map(t.index,t))
4.leetcode242 有效的字母异位词
题目:给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
思路:
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
from collections import Counter
s = Counter(s)
t = Counter(t)
if s == t:
return True
else:
return False
5.leetcode290 单词规律
题目:给定一种规律 pattern 和一个字符串 str ,判断 str 是否遵循相同的规律。这里的 遵循 指完全匹配,例如, pattern 里的每个字母和字符串 str 中的每个非空单词之间存在着双向连接的对应规律。
思路:
class Solution:
def wordPattern(self,pattern, str):
str = str.split()
return list(map(pattern.index,pattern)) == list(map(str.index,str))
6.leetcode349 两个数组的交集
题目:给定两个数组nums,求两个数组的公共元素。
思路:
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
nums1 = set(nums1)
return set([i for i in nums2 if i in nums1])
7.leetcode350 两个数组的交集 2
题目:给定两个数组nums,求两个数组的交集。如nums1=[1,2,2,1],nums=[2,2],结果为[2,2]
思路:
class Solution:
def intersect(self, nums1: List[int], nums2: List[int]) -> List[int]:
from collections import Counter
nums1_dict = Counter(nums1)
res = []
for num in nums2:
if nums1_dict[num] > 0:
res.append(num)
nums1_dict[num] -= 1
return res
8.leetcode410 分割数组的最大值
题目:给定一个非负整数数组和一个整数 m,你需要将这个数组分成 m 个非空的连续子数组。设计一个算法使得这 m 个子数组各自和的最大值最小。
思路:
class Solution:
def splitArray(self, nums: List[int], m: int) -> int:
# 确定二分范围[max(nums),sum(nums)]
left = max(nums)
right = sum(nums)
def check(x):
subSum = 0
cnt = 1
for num in nums:
subSum += num
if subSum > x:
subSum = num
cnt += 1
return cnt <= m
ans = left
while left <= right:
mid = (left + right)//2
if check(mid):
ans = mid
right = mid - 1
else:
left = mid + 1
return ans
9.LeetCode 451 根据字符出现频率排序
题目:给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
思路:
class Solution:
def frequencySort(self, s: str) -> str:
from collections import Counter
s_dict = Counter(s)
# sorted返回的是列表元组
s = sorted(s_dict.items(), key=lambda item:item[1], reverse = True)
# 因为返回的是字符串
res = ''
for key, value in s:
res += key * value
return res
10.leetcode540 有序数组中的单一元素
题目:给定一个只包含整数的有序数组,每个元素都会出现两次,唯有一个数只会出现一次,找出这个数。
思路:
class Solution:
def singleNonDuplicate(self, nums: List[int]) -> int:
left = 0
right = len(nums)-1
while left<right:
mid = (left+right)//2
if (mid == 0 or nums[mid] != nums[mid-1]) and nums[mid] != nums[mid+1]:
return nums[mid]
elif nums[mid] == nums[mid+1]:
if (mid-left)%2 == 0:
left = mid
else:
right = mid-1
else:
if (mid-left+1)%2 == 0:
left = mid+1
else:
right = mid
return nums[left]
参考:https://github.com/datawhalechina/team-learning