小白的LeetCode刷题修炼【python】(1)
LeetCode是一个非常不错的刷题平台,用过的都知道😎,对于像我这样的小白来说里面的题目有点也还算可以,最优势的是你可以看见很多非常不错的刷题思路和方法。
这里我刚刚开刷,每个题目都会自己写一写(没啥参考价值的就不献丑了😁),【5个一组,毕竟不太好写😢】,对于解决方法较好的思路我也会分享给大家,大家也可以在一起讨论,总之各位加油吧!
1.两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值的那两个整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。你可以按任意顺序返回答案
#答案:
class Soultion:
def twoSum(self,nums,target):
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i]+nums[j] == target:
return [i,j]
print(Soultion.twoSum([3,3],6))
#较好的答案
class Solution:
def twoSum(self,nums, target):
hashmap = {}
for index, num in enumerate(nums):
another_num = target - num
if another_num in hashmap:
return [hashmap[another_num], index]
hashmap[num] = index
print(Soultion.twoSum([3,3],6))
#转载处:LeetCode
#作者:magiczsd
#链接:https://leetcode-cn.com/problems/two-sum/solution/hao-shi-12mszai-suo-you-python-ti-jiao-z-5bch/
2.两数相加
给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
#答案
class Solution(object):
def addTwoNumbers(self, l1, l2):
if len(l1) < len(l2):
for i in range(len(l2)-len(l1)):
l1.append(0)
if len(l1) > len(l2):
for i in range(len(l1)-len(l2)):
l2.append(0)
a = [str(i) for i in l1]
b = ''.join(a)[::-1]
A = int(b)
c = [str(i) for i in l2]
d = ''.join(c)[::-1]
B = int(d)
num = A+B
res = str(num)[::-1]
e = list(res)
result = [int(i) for i in e]
return result
print(Solution().addTwoNumbers([9,9,9,9,9,9,9],[9,9,9,9]))
#转载处:LeetCode
#作者:dnanki
#链接:https://leetcode-cn.com/problems/add-two-numbers/solution/di-gui-si-lu-jian-dan-dai-ma-duan-by-dnanki/
3. 无重复字符的最长子串
给定一个字符串,请你找出其中不含有重复字符的最长子串的长度
#答案
class Solution:
def lengthOfLongestSubstring(s: str) -> int:
n = len(s)
longest = 0
end = -1
dic = {}
for i, c in enumerate(s):
if c in dic:
end = max(end, dic[c])
longest = max(longest, i - end)
dic[c] = i
return longest
print(Solution.lengthOfLongestSubstring('pwwkew'))
#转载处:LeetCode
#作者:AIResearcherJHM
#链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/python3zi-dian-ji-lu-mei-ge-zi-fu-zui-hou-chu-xian/
4. 寻找两个正序数组的中位数
给定两个大小为 m 和 n 的正序(从小到大)数组 nums1
和 nums2
。请你找出并返回这两个正序数组的中位数。
#答案
class Solution:
def findMedianSortedArrays(nums1,nums2):
num =(nums1+nums2)
l = len(num)
if l%2 == 0:
mid = float(num[l//2]+num[l//2-1])/2
else:
mid = float(num[l//2])
return mid
print(Solution.findMedianSortedArrays([3,5],[2,4]))
#较好的答案
class Solution:
def findMedianSortedArrays(nums1: List[int], nums2: List[int]) -> float:
def getKthElement(k):
index1, index2 = 0, 0
while True:
# 特殊情况
if index1 == m:
return nums2[index2 + k - 1]
if index2 == n:
return nums1[index1 + k - 1]
if k == 1:
return min(nums1[index1], nums2[index2])
# 正常情况
newIndex1 = min(index1 + k // 2 - 1, m - 1)
newIndex2 = min(index2 + k // 2 - 1, n - 1)
pivot1, pivot2 = nums1[newIndex1], nums2[newIndex2]
if pivot1 <= pivot2:
k -= newIndex1 - index1 + 1
index1 = newIndex1 + 1
else:
k -= newIndex2 - index2 + 1
index2 = newIndex2 + 1
m, n = len(nums1), len(nums2)
totalLength = m + n
if totalLength % 2 == 1:
return getKthElement((totalLength + 1) // 2)
else:
return (getKthElement(totalLength // 2) + getKthElement(totalLength // 2 + 1)) / 2
print(Solution.findMedianSortedArrays([3,5],[2,4]))
#转载处:LeetCode
#作者:LeetCode-Solution
#链接:https://leetcode-cn.com/problems/median-of-two-sorted-arrays/solution/xun-zhao-liang-ge-you-xu-shu-zu-de-zhong-wei-s-114/
较好的方法的解题思路:
假设两个有序数组分别是A 和 B。要找到第 k 个元素,我们可以比较 A[k/2−1] 和 B[k/2−1],其中 //表示整数除法。由于A[k/2−1]和 B[k/2−1] 的前面分别有A[0…k/2−2] 和B[0…k/2−2],即 k/2−1 个元素,对于 A[k/2−1] 和 B[k/2−1] 中的较小值,最多只会有 2(k/2−1)+(k/2−1)≤k−2 个元素比它小,那么它就不能是第 k小的数了。
因此我们可以归纳出三种情况:
-
如果 A[k/2−1]<B[k/2−1],则比 A[k/2−1] 小的数最多只有 A 的前 k/2−1 个数和B 的前k/2−1个数,即比 A[k/2−1] 小的数最多只有 k−2 个,因此 A[k/2−1] 不可能是第 k 个数,A[0] 到 A[k/2−1] 也都不可能是第 k 个数,可以全部排除。
-
如果A[k/2−1]>B[k/2−1],则可以排除B[0] 到 B[k/2−1]。
-
如果 A[k/2−1]=B[k/2−1],则可以归入第一种情况处理。
可以看到,比较A[k/2−1] 和 B[k/2−1] 之后,可以排除 k/2 个不可能是第 k 小的数,查找范围缩小了一半。同时,我们将在排除后的新数组上继续进行二分查找,并且根据我们排除数的个数,减少 k 的值,这是因为我们排除的数都不大于第 k 小的数。
有以下三种情况需要特殊处理:
-
如果 A[k/2−1] 或者 B[k/2−1] 越界,那么我们可以选取对应数组中的最后一个元素。在这种情况下,我们必须根据排除数的个数减少 k 的值,而不能直接将 k 减去k/2。
-
如果一个数组为空,说明该数组中的所有元素都被排除,我们可以直接返回另一个数组中第 k 小的元素。
-
如果k=1,我们只要返回两个数组首元素的最小值即可。
5. 最长回文子串
给你一个字符串 s
,找到 s
中最长的回文子串。
#答案
class Solution:
def longestPalindrome(s: str) -> str:
n = len(s)
dp = [[False] * n for _ in range(n)]
ans = ""
# 枚举子串的长度 l+1
for l in range(n):
# 枚举子串的起始位置 i,这样可以通过 j=i+l 得到子串的结束位置
for i in range(n):
j = i + l
if j >= len(s):
break
if l == 0:
dp[i][j] = True
elif l == 1:
dp[i][j] = (s[i] == s[j])
else:
dp[i][j] = (dp[i + 1][j - 1] and s[i] == s[j])
if dp[i][j] and l + 1 > len(ans):
ans = s[i:j+1]
return ans
print(Solution.longestPalindrome('ababd'))
#转载处:LeetCode
#作者:LeetCode-Solution
#链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode-solution/