给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。
你可以按任意顺序返回答案。
我一开始的解答用了双循环,时间复杂度为O(n2),成功通过
def twoSum(nums,target):
sol=[]
if len(nums)<2:
return sol
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i]+nums[j]==target:
sol.append([i,j])
return sol
之后看了别人的答案,他们用到了字典的方式,达到了O(n)的时间复杂度,dic[nums[i]]=i
这个不能写在下面的if条件之上,原因是每一次遍历不能因为target-nums[i]等于nums[i]
而出现下标与自身相同的情况
def twoSum(nums,target):
dic={
}
for i in range(len(nums)):
#dic[nums[i]]=i # 这个不能写在下面的if条件之上,原因是每一次遍历不能因为
# target-nums[i]=nums[i]而出现下标与自身相同的情况
if target-nums[i] in dic:
return [dic[target-nums[i]],i]
dic[nums[i]]=i # 写在if下面才是对的
在之后自己的改进过程中,我给if语句加了一个判断,反而提高了运行的速率:
def twoSum(nums,target):
dic={
}
for i in range(len(nums)):
if target-nums[i] in dic and dic[target-nums[i]]!=i:
return [dic[target-nums[i]],i]
dic[nums[i]]=i
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。
请你将两个数相加,并以相同形式返回一个表示和的链表。
你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
这个是我的错误答案,在最后的判断中,应该是判断当前的l1与l2是否为空值,因为就算next值为空,也可以指向next节点。同时在声明链表以后还需要声明一个指代这个链表的节点,我理解为c语言中的head
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, val=0, next=None):
# self.val = val
# self.next = next
class Solution:
def addTwoNumbers(self, l1: ListNode, l2: ListNode) -> ListNode:
c=0
l=ListNode(0)
l3=l # 很关键,声明链表以后还需要再声明一个指代这个链表头的节点
while l1 or l2:
a=l1.val if l1 else 0
b=l2.val if l2 else 0
val = a + b + c
c=val//10
l3.next=ListNode(val%10)
l3=l3.next
if l1.next: # 错误
l1=l1.next
if l2.next: # 错误
l2=l2.next
if c>1:
l3.next=ListNode(1)
return l.next
以下是需要修改的地方
if l1: # 若当前值不为空,则去下一个节点
l1=l1.next
if l2:
l2=l2.next
链表是个很基础的题型,以下是自己学习归纳的需要注意的地方:
1)先声明链表头节点
2)声明一个指针指向链表头节点
3)通过指针在while循环中每一次指向自己的next属性,来实现链表的遍历
4)当现在的指针不为空时,就可以指向下一个节点
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
这道题我曾经写出来过,但是用的方法是耗时70多ms,我觉得并不是最优解,这次再看别人的答案,比我的厉害特别多。我的思路是从字符串开头进行遍历,每次与之前的元素做对比,从而获得最优解的数组得出数组长度,但是这种思路非常有局限性,实现起来也很繁琐,如果字符串稍微复杂一点便难以实现。
这位大神的答案十分的言简意赅,他通过字典的方式存储所有字符,直到找到下一个相同的字符,用最后字符的位置加1减去前一个字符的位置取得该不重复字符的长度(因为得包含相同字符中的一个所以要加1),但还是有些没弄懂,得再吸收一下。
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
st = {
}
i, ans = 0, 0
for j in range(len(s)):
if s[j] in st:
i = max(st[s[j]], i)
ans = max(ans, j - i + 1)
st[s[j]] = j + 1
return ans;
这道题如果想直接实现的话其实并不难,但作为一道Hard难度的题目,他将答案的时间复杂度限制在O(log(m+n))。
我之后再来填补这道题吧,现在确实看着有些繁琐。
给你一个字符串 s,找到 s 中最长的回文子串。
被整吐了,先是自己尝试用暴力破解法失败了,看了官方解释的中心扩散法也失败了,最后还是看着答案搞完的,自己归纳了几个需要注意的点:
judge
来判断长度的奇偶性从而进行分类讨论,但是我对于回文序列的思路想错了,不论是奇数字符串还是偶数字符串是都有可能有奇偶回文序列的。这个标志位应该是针对回文序列而不是针对原字符串,这也导致了我的写法无法得到正确的解left
和right
变量变成与索引i相减和相加得到回文序列的起点和终点,虽然这样可行,但是对于边界的处理会很复杂,不如直接如答案中将left
和right
直接设置为起点和终点findCenter(s,left,right)
这个函数的设计,因为并不知道这个字符串中回文序列的奇偶性,当调用这个函数时,不仅可以让奇偶同时被讨论,而且对于答案互不影响。class Solution:
def longestPalindrome(self, s: str) -> str:
def findCenter(s,left,right):#放上面
while left>=0 and right<len(s) and s[left]==s[right]:
left-=1
right+=1
return left+1,right-1
if len(s)<2:
return s
judge=0 if len(s)%2==0 else 1 #本来是用来判断长度的奇偶性从而分类讨论
start,end=0,0
maxLen=0
lst=[]
for i in range(len(s)):
#if judge ==1:
left1,right1= findCenter(s,i,i)
if right1-left1>end-start:
start,end=left1,right1
# if right-left>maxLen:
# maxLen=right-left
# lst=[left,right]
#else:
left2,right2=findCenter(s,i,i+1)
if right2-left2>end-start:
start,end=left2,right2
# if abs(right-left)>maxLen:
# maxLen=abs(right-left)
# lst=[left,right]
sol=s[start:end+1]
return sol
list1=list2
,这只会让他们地址相同而一起发生改变,要使用切片:list1[:]=list2[:]
。//
。