Problem 2. Add Two Numbers
给定两个链表,每个元素代表一个数位,返回求和结果的链表,譬如:
(2→4→3)+(5→6→4)=7→0→8
,最开始是最低位,即个位。
解题思路:遍历求和,采用尾插法建立新链表即可。
def addTwoNumbers(self, l1, l2):
t1 = l1
t2 = l2
root = n = ListNode(0)
carry = 0
while t1 or t2 or carry:
sum = 0
if t1:
sum += t1.val
t1 = t1.next
if t2:
sum += t2.val
t2 = t2.next
carry, res = divmod(sum+carry, 10)
n.next = ListNode(res)
n = n.next
return root.next
Problem 3. Longest Substring Without Repeating Characters
给定一个字符串s,返回不包含重复值的最长子串的长度。
解题思路:遍历数组,如果当前值s[i]不在s[index:i]中,则我们可以直接将子串长度加1;如果在,我们找到s[i]出现的位置j,则新串的长度为j到i,同时更新index = j +1,注意,我们必须保证在任何时候[index:i]不存在重复字符,然后比较当前长度与max_length的大小。时间复杂度 O(n) 。
def lengthOfLongestSubstring(self, s):
if not s:
return 0
max_length = 1
t_max = 1
index = 0
for i in range(1, len(s)):
t_max = i - s[index:i].find(s[i]) - index#find,如果不存在,则返回-1,正好此时长度加1,因此可以将当前元素是否存在于当前子串的两者情况合并。
index += s[index:i].find(s[i]) + 1
max_length = max(max_length, t_max)
return max_length
Problem 5. Longest Palindromic Substring
给定一个字符串s,返回最长回文子串。
解题思路:有两种解法,第一种DP,即我们考虑以第i个字符结尾的最长回文子串s[i],此时s[i-1]长度为l,分三种情况:
- s[i-l-1] = s[i],则s[i] = s[i-1] +2
- s[i-l:i+1](不包括i+1)构成回文,则s[i] = s[i-1] +1
- s[i-l+1:i+1]构成回文,则s[i] = s[i-1]
第二种思路,即考虑,从数组的每个位置向两边扩张,求得最长的回文长度,注意,在每个位置需要分两种情况讨论,奇数,则从i向两边扩;偶数,则分别从i和i+1向两边扩。
def extend(self,s,l,r):
while l>=0 and r<len(s) and s[l]==s[r]:
l -= 1
r += 1
return l+1, r-l-1
def longestPalindrome(self, s):
max_length = start = 0
if len(s) < 2:
return s
for i in range(len(s) - 1):
s1, l_odd = self.extend(s, i, i)
s2, l_even = self.extend(s, i, i+1)
if max_length < max(l_even,l_odd):
max_length = max(l_even,l_odd)
start = s1 if l_odd > l_even else s2
return s[start:start+max_length]