Array & Strings
我一直觉得Array & Strings的题目是最烦的。因为不仅仅要考虑corner case。写起来还非常费力。
283 Move Zeroes
一开始写的办法真是笨,类似于冒泡排序的办法,不停的把数字往前面冒泡,这样sort完,0就在最后面了。 后来发现,其实只要把数字按照顺序移动到前面去,然后把后面的数全部制0就行了。
class Solution(object):
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
if len(nums) <= 1:
return
index = 1
while index<len(nums):
if nums[index-1] == 0:
tmpIndex = index
while tmpIndex != 0 and nums[tmpIndex-1] == 0:
nums[tmpIndex], nums[tmpIndex -1] = nums[tmpIndex - 1], nums[tmpIndex]
tmpIndex -= 1
index += 1
return nums
s = Solution()
print s.moveZeroes([0, 1, 0, 3, 12])
#Better Solution
class Solution(object):
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: void Do not return anything, modify nums in-place instead.
"""
pos = 0
for n in nums:
if n!=0:
nums[pos] = n
pos+=1
nums[pos:] = [0]*(len(nums)-pos)
s = Solution()
print s.moveZeroes([0, 1, 0, 3, 12])
68 Add Binary
这道题其实用python黑魔法一行就出来了。不过面试肯定不能这样。最后的写法还是类似于big number sum。
class Solution(object):
def addBinary(self, a, b):
"""
:type a: str
:type b: str
:rtype: str
"""
# print bin(int(a,2) + int(b,2))[2:]
a = list(a)[::-1]
b = list(b)[::-1]
if len(a)<len(b):
a, b = b, a
carry = 0
i = 0
while i<len(a):
bVal = int(b[i]) if i<len(b) else 0
curSum = bVal + int(a[i]) + carry
a[i] = str(curSum%2)
carry = curSum//2
i += 1
if carry:
a.append(str(carry))
return ''.join(a[::-1])
s = Solution()
print s.addBinary("11", "1")
350 Intersection of Two Arrays II
这道题除了用conter取巧以外,还可以先sort了,然后再用两个pointer来存结果。
import collections
class Solution(object):
def intersect(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
c1 = collections.Counter(nums1)
c2 = collections.Counter(nums2)
c = c1 & c2
return [ k for k, v in c.items() for _ in range(v) ]
s = Solution()
s.intersect([1, 2, 2, 1], [2, 2])
15 3Sum
这道经典种的经典题目。其实可以用combination sum的套路来解。不过复杂度是O(n^3),而且超时了。所以还是得用。sort()后,定点然后左右两个pointer来做。
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if len(nums) < 3:
return []
nums.sort()
return self.helper(nums, [], 0, [])
def helper(self, nums, path, sum, res):
if len(path) == 3 and sum == 0:
res.append(path)
return
if not nums:
return
for i in range(len(nums)):
if i>0 and nums[i]==nums[i-1]:
continue
self.helper(nums[i+1:], path + [nums[i]], sum + nums[i], res)
return res
s = Solution()
print s.threeSum([-1, 0, 1, 2, -1, -4])
然后我们再用经典做法。我的建议是先写出不handle dup的,然后再一点一点往上加dedup。
class Solution(object):
def threeSum(self, nums):
"""
:type nums: List[int]
:rtype: List[List[int]]
"""
if len(nums) < 3:
return []
nums.sort()
res = []
for i in range(len(nums)-2):
if i>0 and nums[i] == nums[i-1]: # dedup
continue
num = nums[i]
l, r = i+1, len(nums)-1
while l<r:
sum = num + nums[l] + nums[r]
if l>i+1 and nums[l]==nums[l-1]: # dedup
l += 1
elif sum == 0:
res.append([num, nums[l], nums[r]])
l, r = l+1, r-1
elif sum > 0:
r -= 1
else:
l += 1
return res
s = Solution()
print s.threeSum([-2,0,0,2,2])
125 Valid Palindrome
嗯。两个pointer.
class Solution(object):
def isPalindrome(self, s):
"""
:type s: str
:rtype: bool
"""
if not s:
return True
l, r = 0, len(s)-1
while l <= r:
while l<r and not s[l].isalnum():
l += 1
while r>l and not s[r].isalnum():
r -= 1
if s[l].lower() == s[r].lower():
l += 1
r -= 1
else:
return False
return True
s = Solution()
print s.isPalindrome("P0")
Trapping Rain Water
我记得这道题,还有一个2D的版本。具体思想就是我们一直找那个最短的木板向里推进。然后存好外围最矮的那个。
class Solution(object):
def trap(self, height):
"""
:type height: List[int]
:rtype: int
"""
if not height:
return 0
l, r = 0, len(height) - 1
l_height, r_height = height[l], height[r]
res = 0
while l < r:
if height[l] <= height[r]:
l += 1
if height[l] < l_height:
res += l_height - height[l]
else:
l_height = height[l]
else:
r -= 1
if height[r] < r_height:
res += r_height - height[r]
else:
r_height = height[r]
return res