除自身以外数组的乘积
Given an arraynums
of
n
integers where
n
> 1, return an array
output
such that
output[i]
is equal to the product of all the elements of
nums
except
nums[i]
.
Example:
Input:[1,2,3,4]
Output:[24,12,8,6]
Code(By myself):
class Solution(object):
def productExceptSelf(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
res = []
temp = 1
for i in range(len(nums)):
res.append(temp)
temp = temp * nums[i]
temp = 1
for i in range(len(nums)-1,-1,-1):
res[i] = res[i] * temp
temp = temp * nums[i]
return res
总结:
可使用二进制加法运算求出结果
螺旋矩阵
Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
Example:
Input: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] Output: [1,2,3,6,9,8,7,4,5]
Code(By myself):
class Solution(object):
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
res = []
if not matrix:
return res
top = 0
bottom = len(matrix) - 1
left = 0
right = len(matrix[0]) - 1
i = 0
j = 0
length = len(matrix) * len(matrix[0])
while True:
while j <= right and len(res) < length:
res.append(matrix[i][j])
j += 1
j = right
i += 1
top += 1
while i <= bottom and len(res) < length:
res.append(matrix[i][j])
i += 1
i = bottom
j -= 1
right -= 1
while j >= left and len(res) < length:
res.append(matrix[i][j])
j -= 1
j = left
i -= 1
bottom -= 1
while i >= top and len(res) < length:
res.append(matrix[i][j])
i -= 1
i = top
j += 1
left += 1
if len(res) == length:
break
return res
Code(others):
class Solution(object):
def spiralOrder(self, matrix):
"""
:type matrix: List[List[int]]
:rtype: List[int]
"""
ans = []
while matrix:
ans += matrix.pop(0)
if matrix and matrix[0]:
for row in matrix:
ans.append(row.pop())
if matrix:
ans += matrix.pop()[::-1]
if matrix and matrix[0]:
for row in matrix[::-1]:
ans.append(row.pop(0))
return ans
四数之和
Given four lists A, B, C, D of integer values, compute how many tuples (i, j, k, l)
there are such that A[i] + B[j] + C[k] + D[l]
is zero.
To make problem a bit easier, all A, B, C, D have same length of N where 0 ≤ N ≤ 500. All integers are in the range of -228 to 228 - 1 and the result is guaranteed to be at most 231 - 1.
Example:
Input: A = [ 1, 2] B = [-2,-1] C = [-1, 2] D = [ 0, 2] Output: 2 Explanation: The two tuples are: 1. (0, 0, 0, 1) -> A[0] + B[0] + C[0] + D[1] = 1 + (-2) + (-1) + 2 = 0 2. (1, 1, 0, 0) -> A[1] + B[1] + C[0] + D[0] = 2 + (-1) + (-1) + 0 = 0
Code(By myself):
class Solution(object):
def fourSumCount(self, A, B, C, D):
"""
:type A: List[int]
:type B: List[int]
:type C: List[int]
:type D: List[int]
:rtype: int
"""
n = 0
if len(A) == 0:
return n
dic = {}
for i in A:
for j in B:
if i+j not in dic:
dic[i+j] = 1
else:
dic[i+j] += 1
for i in C:
for j in D:
if -i-j in dic:
n += dic[-i-j]
return n
盛最多水的容器
Given n non-negative integers a1, a2, ..., an, where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
Note: You may not slant the container and n is at least 2.
Code(By myself):
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
maxVolumn = 0
temp = []
for i in range(len(height)):
temp.append((height[i],i))
temp.sort(key = lambda x : x[0])
while True:
if len(temp) == 1:
break
maxVolumn = max(maxVolumn,temp[0][0] * max(temp[0][1]-min(temp,key = lambda x:x[1])[1],max(temp,key = lambda x:x[1])[1]-temp[0][1]))
temp.pop(0)
return maxVolumn
Code(others):
class Solution(object):
def maxArea(self, height):
"""
:type height: List[int]
:rtype: int
"""
l = 0
r = len(height)-1
if not height or len(height) == 1 :
return 0
res = (r-l)*(height[l] if height[l] < height[r] else height[r])
while l < r:
if height[l] < height[r] :
res = res if res > height[l]*(r-l) else height[l]*(r-l)
l += 1
else :
res = res if res > height[r]*(r-l) else height[r]*(r-l)
r -=1
return res
总结:
容器的体积只与短边相关,左右各置一个指针,小的便移动。
生命游戏
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellular automaton devised by the British mathematician John Horton Conway in 1970."
Given a board with m by n cells, each cell has an initial state live (1) or dead (0). Each cell interacts with its eight neighbors (horizontal, vertical, diagonal) using the following four rules (taken from the above Wikipedia article):
- Any live cell with fewer than two live neighbors dies, as if caused by under-population.
- Any live cell with two or three live neighbors lives on to the next generation.
- Any live cell with more than three live neighbors dies, as if by over-population..
- Any dead cell with exactly three live neighbors becomes a live cell, as if by reproduction.
Write a function to compute the next state (after one update) of the board given its current state. The next state is created by applying the above rules simultaneously to every cell in the current state, where births and deaths occur simultaneously.
Example:
Input: [ [0,1,0], [0,0,1], [1,1,1], [0,0,0] ] Output: [ [0,0,0], [1,0,1], [0,1,1], [0,1,0] ]
Code(By myself):
class Solution(object):
def gameOfLife(self, board):
"""
:type board: List[List[int]]
:rtype: void Do not return anything, modify board in-place instead.
"""
self.row = len(board)
self.col = len(board[0])
for i in range(self.row):
for j in range(self.col):
if board[i][j] == 0:
board[i][j] -= self.sumRound(board,i,j)
else:
board[i][j] += self.sumRound(board,i,j)
for i in range(self.row):
for j in range(self.col):
board[i][j] = self.judge(board[i][j])
def sumRound(self,board,i,j):
count = 0
if i - 1 >= 0:
if j - 1 >= 0 and board[i-1][j-1] > 0:
count += 1
if j + 1 < self.col and board[i-1][j+1] > 0:
count += 1
if board[i-1][j] > 0:
count += 1
if i + 1 < self.row:
if j - 1 >= 0 and board[i+1][j-1] > 0:
count += 1
if j + 1 < self.col and board[i+1][j+1] > 0:
count += 1
if board[i+1][j] > 0:
count += 1
if j - 1 >= 0 and board[i][j-1] > 0:
count += 1
if j + 1 < self.col and board[i][j+1] > 0:
count += 1
return count
def judge(self,n):
if n <= 0:
n = -n
if n <= 2 or n > 3:
return 0
else:
return 1
else:
n = n - 1
if n < 2 or n > 3:
return 0
else:
return 1
Code(others):
class Solution(object):
def gameOfLife(self, board):
"""
:type board: List[List[int]]
:rtype: void Do not return anything, modify board in-place instead.
"""
for i in range(len(board)):
for j in range(len(board[0])):
one_count = self.count(board, i, j)
if board[i][j] ==1:
if one_count < 2 or one_count > 3:
board[i][j] = 3
if board[i][j] == 0:
if one_count == 3:
board [i][j] = 2
for i in range(len(board)):
for j in range(len(board[0])):
if board[i][j] == 3:
board[i][j] = 0
if board[i][j] == 2:
board[i][j] = 1
def count(self, board, i, j):
count = 0
if i > 0 and j > 0:
if board[i - 1][j - 1] == 1 or board[i - 1][j - 1] == 3:
count += 1
if i > 0:
if board[i - 1][j] == 1 or board[i - 1][j] == 3:
count += 1
if i > 0 and j + 1 < len(board[0]):
if board[i - 1][j + 1] ==1 or board[i - 1][j + 1] == 3:
count += 1
if j > 0:
if board[i][j - 1] == 1 or board[i][j - 1] == 3:
count += 1
if j + 1 < len(board[0]):
if board[i][j + 1] == 1 or board[i][j + 1] == 3:
count += 1
if i + 1 < len(board) and j > 0:
if board[i + 1][j - 1] == 1 or board[i + 1][j - 1] == 3:
count += 1
if i + 1 < len(board):
if board[i + 1][j] == 1 or board[i + 1][j] == 3:
count += 1
if i + 1 < len(board) and j + 1 < len(board[0]):
if board[i + 1][j + 1] == 1 or board[i + 1][j + 1] == 3:
count += 1
return count
总结:可以使用状态机转换: 状态0: 死细胞转为死细胞 状态1: 活细胞转为活细胞 状态2: 活细胞转为死细胞 状态3: 死细胞转为活细胞 最后我们对所有状态对2取余,那么状态0和2就变成死细胞,状态1和3就是活细胞,达成目的。我们先对原数组进行逐个扫描,对于每一个位置,扫描其周围八个位置,如果遇到状态1或2,就计数器累加1,扫完8个邻居,如果少于两个活细胞或者大于三个活细胞,而且当前位置是活细胞的话,标记状态2,如果正好有三个活细胞且当前是死细胞的话,标记状态3。完成一遍扫描后再对数据扫描一遍,对2取余变成我们想要的结果。
缺失的第一个正整数
Given an unsorted integer array, find the smallest missing positive integer.Example:
Input: [1,2,0] Output: 3
Code(By myself):
class Solution(object):
def firstMissingPositive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
left = 1
if not nums:
return left
right = max(nums) + 1
for i in range(left,right):
if i not in nums:
return i
return right
Code(others):
class Solution(object):
def firstMissingPositive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums.append(0)
n=len(nums)
for i in range(len(nums)):
if nums[i]<0 or nums[i]>=n:
nums[i]=0
for num in nums:
nums[num%n]+=n
i=0
while i<n and nums[i]>=n:
i+=1
return i
总结:
利用列表下标查找缺失值。
滑动窗口最大值
Given an array nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position. Return the max sliding window.
Example:
Input: nums = [1,3,-1,-3,5,3,6,7], and k = 3
Output: [3,3,5,5,6,7]
Explanation:
Window position Max
--------------- -----
[1 3 -1] -3 5 3 6 7 3
1 [3 -1 -3] 5 3 6 7 3
1 3 [-1 -3 5] 3 6 7 5
1 3 -1 [-3 5 3] 6 7 5
1 3 -1 -3 [5 3 6] 7 6
1 3 -1 -3 5 [3 6 7] 7
Code(By myself):
class Solution(object):
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
res = []
if len(nums) == 0:
return res
if len(nums) == 1:
return nums
i = 0
maxInf = [nums[0],0]
while i + k - 1 < len(nums):
if i == 0 or i > maxInf[1]:
maxInf = [-float('inf'),-float('inf')]
for j in range(i,i+k):
if nums[j] > maxInf[0]:
maxInf = [nums[j],j]
if nums[i+k-1] > maxInf[0]:
maxInf = [nums[i+k-1],i+k-1]
res.append(maxInf[0])
i += 1
return res
Code(others):
class Solution:
def maxSlidingWindow(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: List[int]
"""
if k == 0 or k > len(nums):
return []
maximum = max(nums[0:k])
ans = [maximum]
# nums.append(float('-inf'))
for left in range(len(nums) - k):
if nums[left + k] > maximum:
maximum = nums[left + k]
elif nums[left] == maximum:
maximum = max(nums[left + 1:left + k + 1])
ans.append(maximum)
return ans
最长连续序列
Given an unsorted array of integers, find the length of the longest consecutive elements sequence.
Your algorithm should run in O(n) complexity.
Example:
Input: [100, 4, 200, 1, 3, 2]
Output: 4
Explanation: The longest consecutive elements sequence is [1, 2, 3, 4]
. Therefore its length is 4.
Code(By myself):
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
maxLen = 0
nums = sorted(nums)
i = 0
while i < len(nums):
temp = 1
j = i
while j < len(nums) - 1 and (nums[j] + 1 == nums[j+1] or nums[j] == nums[j+1]):
if nums[j] + 1 == nums[j+1]:
temp += 1
j += 1
else:
j += 1
maxLen = max(maxLen,temp)
i = j + 1
return maxLen
Code(others):
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
c = 1
n = 1
v = None
# suppose it's radix sort or counting sort, so it's O(n)
for x in sorted(set(nums)):
if v != x - 1:
c = 1
else:
c += 1
if c > n:
n = c
v = x
return n
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
nums = set(nums)
max_len = 0
for num in nums:
if num - 1 not in nums:
cur_len = 1
while num + 1 in nums:
cur_len += 1
num += 1
max_len = max(max_len, cur_len)
return max_len
class Solution(object):
def longestConsecutive(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
if len(nums) == 1:
return 1
dic = {}
res = 1
nums = set(nums)
for i in nums:
res = max(res,self.helper(i,dic,nums))
return res
def helper(self,val,dic,nums):
if val in dic:
return dic[val]
if val - 1 in nums:
dic[val] = 1 + self.helper(val - 1,dic,nums)
else:
dic[val] = 1
return dic[val]
总结:
- 排序后通过遍历通过nums[i]+1 == nums[i+1]判断是否连续,求最大连续序列长度
- 排序后通过nums[i]+1 in nums判断是否连续
- 建立hash表,在递归中若nums[i]-1 in nums,则带入nums[i]-1重复本过程
寻找重复数
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than O(n2).
- There is only one duplicate number in the array, but it could be repeated more than once.
Example:
Input: [1,3,4,2,2]
Output: 2
Code(By myself):
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
realSum = sum(nums)
setSum = sum(set(nums))
lenNums = len(nums)
lenSet = len(set(nums))
return (realSum-setSum)/(lenNums-lenSet)
# for i in range(len(nums)): # if self.find(nums[i+1:],nums[i]): # return nums[i] # def find(self,nums,n): # if nums[0] == n: # return True # if len(nums) == 1: # return False # if self.find(nums[:len(nums)//2],n) or self.find(nums[len(nums)//2:],n): # return True # else: # return False
两层循环以及递归均未通过时间限制,没想到太好的方法,只好用set()来通过,不过空间复杂度不是O(1)
Code(others):
"""
In this problem, nums[a] = b can be seen as a.next = b,
the the problem is exactly the same as Linked List Cycle II which finds the node that cycle begins.
"""
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if len(nums) < 1:
return None
# find cycle
fast = nums[0]
slow = nums[0]
while True:
fast = nums[nums[fast]]
slow = nums[slow]
if (fast == slow):
break
# find node
fast = nums[0]
while fast != slow:
fast = nums[fast]
slow = nums[slow]
return fast
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
l = 1
r = len(nums) - 1
while l <= r:
mid = (l + r) >> 1
count = sum([1 for i in nums if i <= mid])
if count <= mid:
l = mid + 1
else:
r = mid - 1
return l
总结:
- 可以将表看出是有环的静态链表,首先找到环的位置,再找重复的元素
- 通过中位数与小于其值元素的个数进行比较来判断重复值的位置
最小覆盖字串
Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n).Example:
Input: S = "ADOBECODEBANC", T = "ABC" Output: "BANC"
Code(By myself):
class Solution(object):
def minWindow(self, s, t):
"""
:type s: str
:type t: str
:rtype: str
"""
tLength = len(t)
sLength = len(s)
dic = {}
for i in t:
if i not in dic:
dic[i] = 1
else:
dic[i] += 1
begin, end, count = 0, 0, 0
res = ''
while end < sLength:
#除去窗口开始部分不在t中元素
if s[end] in dic:
if dic[s[end]] > 0:
count += 1
dic[s[end]] -= 1
if count == tLength:
while s[begin] not in dic or dic[s[begin]] < 0:
if s[begin] in dic:
dic[s[begin]] += 1
begin += 1
if end - begin + 1 < len(res) or not res:
res = s[begin:end+1]
end += 1
if len(res) >= tLength:
return res
else:
return ''
Code(others):
class Solution(object):
def minWindow(self, s, t):
"""
:type s: str
:type t: str
:rtype: str
"""
mp=collections.defaultdict(int)
for c in t:
mp[c]+=1
count=len(mp)
begin=head=0
d=float('inf')
for end in range(len(s)):
tmp=s[end]
if tmp in mp:
mp[tmp]-=1
if mp[tmp]==0:
count-=1
while count==0:
if d>end-begin:
d=end-begin+1
head=begin
tmp=s[begin]
if tmp in mp:
mp[tmp]+=1
if mp[tmp]>0:
count+=1
begin+=1
if d==float('inf'):
return ''
else:
return s[head:head+d]
总结:
此类问题均可用哈希表与两个指针完成,同时count用来记录窗口中t中有效字符的个数,多余的不计数。当count等于t的长度之后,end指针找到与begin所指相同的字符,开始从左收缩窗口,到再次指向另一个有效且不多余字符为止,过程中更新最小窗口。
基本计算器Ⅱ
Implement a basic calculator to evaluate a simple expression string.
The expression string contains only non-negative integers, +
, -
, *
, /
operators and empty spaces . The integer division should truncate toward zero.
Example:
Input: "3+2*2" Output: 7
Code(By myself):
class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
numStack = []
strStack = []
i = 0
res = 0
while i < len(s):
if s[i] == '+' or s[i] == '-':
strStack.append(s[i])
elif s[i] == '*' or s[i] == '/':
num = s[i+1]
j = i + 2
while j < len(s) and s[j] != '+' and s[j] != '-' and s[j] != '*' and s[j] != '/':
num += s[j]
j += 1
if s[i] == '*':
numStack.append(numStack.pop()*int(num))
else:
numStack.append(numStack.pop()//int(num))
i = j - 1
else:
num = s[i]
j = i + 1
while j < len(s) and s[j] != '+' and s[j] != '-' and s[j] != '*' and s[j] != '/':
num += s[j]
j += 1
numStack.append(int(num))
i = j - 1
i += 1
res = numStack.pop(0)
while numStack:
a = numStack.pop(0)
if strStack.pop(0) == '+':
res += a
else:
res -= a
return res
Code(others):
class Solution(object):
def calculate(self, s):
"""
:type s: str
:rtype: int
"""
stack=[]
num=0
pre='+'
s=s+'+'
for n in s:
if n.isdigit():
num=num*10+ord(n)-ord('0')
elif n==' ':
continue
else:
if pre=='+':
stack.append(num)
elif pre=='-':
stack.append(-num)
elif pre=='*':
stack[-1]*=num
else:
stack[-1]=int(stack[-1]*1.0/num)
pre=n
num=0
return sum(stack)
总结:
利用栈解决计算器问题。