1. Two Sum
Given an array of integers, return indices of the two numbers such that they add up to a specific target.
You may assume that each input would have exactly one solution, and you may not use the same element twice.
Example:
Given nums = [2, 7, 11, 15], target = 9,
Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
最简单的想法, 遍历所有的数,两两组合,满足条件就返回:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
ret = []
for i in range(len(nums)):
for j in range(len(nums)):
if (i != j) and nums[i] + nums[j] == target:
return [i, j]
结果:超时
改进:用字典保存已扫描过的数及其下标,扫到一个数x时,字典中查找target - x是否在字典中,若在则找到结果。
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
d = {}
length = len(nums)
for i in range(length):
if target - nums[i] in d:
j = d.get(target - nums[i])
if j != i:
return [i, j]
d[nums[i]] = i
solution = Solution()
nums = [3, 2, 4]
target = 6
ans = solution.twoSum(nums, target)
print(ans)
结果:Beat 97.41% python3 at 2018-4-21
2. Add Two Numbers
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.
Example
Input: (2 -> 4 -> 3) + (5 -> 6 -> 4)
Output: 7 -> 0 -> 8
Explanation: 342 + 465 = 807.
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if l1 is None or l2 is None:
return None
ans = None
tail = None
while l1 is not None or l2 is not None:
node = ListNode(0)
if l1 is not None:
node.val += l1.val
l1 = l1.next
if l2 is not None:
node.val += l2.val
l2 = l2.next
if ans is None:
ans = node
else:
tail.next = node
tail = node
tail = ans
carry = False
while True:
if carry:
tail.val += 1
carry = False
if tail.val >= 10:
tail.val -= 10
carry = True
if tail.next is None:
break
tail = tail.next
if carry:
node = ListNode(1)
tail.next = node
return ans
简单的想法:
一一对应地将两个链表加起来,如果一个链已经到结尾则只加另一个。
扫描一遍结果的链表,有进位则处理进位。
结果 Beat 94.01% python3 at 2018-04-22
优化:复用链表的节点
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def addTwoNumbers(self, l1, l2):
"""
:type l1: ListNode
:type l2: ListNode
:rtype: ListNode
"""
if l1 is None or l2 is None:
return None
p1, p2 = l1, l2
t1, t1 = l1, l2
carry = 0
while p1 != None and p2 != None:
p1.val += p2.val + carry
carry = p1.val // 10
p1.val %= 10
p2.val = p1.val
t1, t2 = p1, p2
p1, p2 = p1.next, p2.next
ans, tail, p = l1, t1, p1
if p2 != None:
ans, tail, p = l2, t2, p2
while p != None:
p.val += carry
carry = p.val // 10
p.val %= 10
tail = p
p = p.next
if carry:
tail.next = ListNode(carry)
return ans
结果 Beat 99.68% python3 at 2018-05-02
3. Longest Substring Without Repeating Characters
Given a string, find the length of the longest substring without repeating characters.
Examples:
Given “abcabcbb”, the answer is “abc”, which the length is 3.
Given “bbbbb”, the answer is “b”, with the length of 1.
Given “pwwkew”, the answer is “wke”, with the length of 3. Note that the answer must be a substring, “pwke” is a subsequence and not a substring.
没有重复字符的子串,简单的想法,用一个256大小的数组表示256个字符是否已出现过,初始化为全0,begin, end维护一个不含重复字符的子串的范围,end一直往后找,直到找到一个已在这个序列中的字符为止,找到后begin 向前移动,直到找到跟end相同的字符,保持[begin, end) 不含相同字符。
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
length = len(s)
if length == 0:
return 0
begin = 0
end = begin + 1
ans = 1
m = [ 0 for i in range(256) ]
m[ord(s[begin])] = 1
while end < length:
if m[ord(s[end])] != 0:
while begin <= end:
m[ord(s[begin])] = 0
begin += 1
if s[begin-1] == s[end]:
break
m[ord(s[end])] = 1
end += 1
ans = max(ans, end - begin)
return ans
Beat 50.04% python3 at 2018-04-23
优化:当找到一个已存在的字符时,begin有个一直前移,找到跟end相同字符的动作,用m之间记录这个位置,可省略这个往前移动的动作:
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
length = len(s)
if length == 0:
return 0
begin = -1
ans = 0
m = [ 0 for i in range(256) ]
for end, c in enumerate(s):
begin = max(begin, m[ord(c)])
m[ord(c)] = end + 1
ans = max(ans, end - begin + 1)
return ans
Beat 63.11% python3 at 2018-04-23
还是不太理想,将m 从list换成dict:
class Solution:
def lengthOfLongestSubstring(self, s):
"""
:type s: str
:rtype: int
"""
begin = -1
ans = 0
dict = {}
for end, c in enumerate(s):
if c in dict and dict[c] > begin:
begin = dict[c]
else:
ans = max(ans, end-begin)
dict[c] = end
return ans
Beat 99.20% python3 at 2018-04-23
647. Palindromic Substrings
Given a string, your task is to count how many palindromic substrings in this string.
The substrings with different start indexes or end indexes are counted as different substrings even they consist of same characters.
Example 1:
Input: “abc”
Output: 3
Explanation: Three palindromic strings: “a”, “b”, “c”.
Example 2:
Input: “aaa”
Output: 6
Explanation: Six palindromic strings: “a”, “a”, “a”, “aa”, “aa”, “aaa”.
Note:
The input string length won’t exceed 1000.
方法:让每一个字母当中点,有两类回文方式:
1) axa
2) axxa
class Solution:
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
ans = 0
length = len(s)
for i in range(length):
j = 0
while i - j >= 0 and i + j < length and s[i-j] == s[i+j]:
j += 1
ans += 1
j = 0
while i - j >= 0 and i + j + 1 < length and s[i-j] == s[i+j+1]:
j += 1
ans += 1
return ans
Beat 71.9% python3 at 2018-04-24
优化:数一下连续的相同字母,如连续3个a:aaa
回文串数a, a, a, aa, aa, aaa,个数3 + 2 + 1 = n*(n+1) / 2
然后从两个边界开始往两边数,比如baab,数到中间a时,连续两个a
aa往两边扩展都是b,得到baab,+1
class Solution:
def countSubstrings(self, s):
"""
:type s: str
:rtype: int
"""
ans = 0
length = len(s)
i = 0
while i < length:
j = i
while j < length and s[j] == s[i]:
j += 1
ans += (j - i) * (j - i + 1) // 2
l, r = i - 1, j
while l >= 0 and r < length and s[l] == s[r]:
l -= 1
r += 1
ans += 1
i = j
return ans
Beat 100.0% python3 at 2018-04-24
20. Valid Parentheses
Given a string containing just the characters ‘(‘, ‘)’, ‘{‘, ‘}’, ‘[’ and ‘]’, determine if the input string is valid.
An input string is valid if:
Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
Note that an empty string is also considered valid.
Example 1:
Input: “()”
Output: true
Example 2:
Input: “()[]{}”
Output: true
Example 3:
Input: “(]”
Output: false
Example 4:
Input: “([)]”
Output: false
Example 5:
Input: “{[]}”
Output: true
方法:使用栈碰到左半边就入栈,碰到右半边则与栈顶匹配
class Solution:
def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
if len(s) % 2 != 0:
return False
l = []
for c in s:
if c == '(' or c == '[' or c == '{':
l.append(c)
else:
if len(l) == 0:
return False
top = l[-1]
if c == ')' and top != '(':
return False
elif c == ']' and top != '[':
return False
elif c == '}' and top != '{':
return False
l.pop()
return len(l) == 0
Beat 90.78% python3 at 2018-04-25
优化:使用双端队列代替list
from collections import deque
class Solution:
def isValid(self, s):
"""
:type s: str
:rtype: bool
"""
if len(s) % 2 != 0:
return False
deq = deque()
for c in s:
if c == '(' or c == '[' or c == '{':
deq.append(c)
else:
if len(deq) == 0:
return False
top = deq[-1]
if c == ')' and top != '(':
return False
elif c == ']' and top != '[':
return False
elif c == '}' and top != '{':
return False
deq.pop()
return len(deq) == 0
Beat 99.85% python3 at 2018-04-25