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, return [0, 1].
Approach 1: Brute Force
- 两个循环,两两相加
- TC:O(n^2) SC:O(1)
Approach 2: Two-pass Hash Table
- 引入哈希表,用空间换时间(利用了哈希表判断key是否存在的复杂度为O(1)的特性)
- 第一次遍历建表(key为num[i], value为i),第二次遍历判断target-num[i]的key是否存在(注意要加一个判断来排除自己加自己等于target的情况)
- TC:O(n) SC:O(n)
Approach 3: One-pass Hash Table
- 在第一次遍历建表时,就判断目标元素是否存在,从而进一步压缩算法用时。
7 Reverse Integer
Given a 32-bit signed integer, reverse digits of an integer.
Example:
Input: 123, Output: 321
Input: -123, Output: -321
Input: 120, Output: 21
Note: the 32-bit signed integer range: [−2^31, 2^31 − 1]. Returns 0 when the reversed integer overflows.
Approach:
- 解题思路与翻转字符串类似:不断地取出input的最后一位数,把它装到另一个数中
- 由于整数的特殊性,因此我们可以用数学方法代替辅助的栈/数组
- input先对10取余,然后整除10,这样我们就取出了最后一个数
- rev先乘以10,再加上从input中取出的数,就完成了这位数的装入
- 注意,在rev乘10之前,要先对溢出做判断,比较它与溢出限除以10的大小,如果二者相等,则需要对尾数(装入的那位数)做判断
- 正负上限分开判别:
if (rev > INT_MAX/10 || (rev == INT_MAX / 10 && pop > 7))
if (rev < INT_MIN/10 || (rev == INT_MIN / 10 && pop < -8))
- 正负上限分开判别:
- TC: O(log(n)), SC:O(1)
- 时间复杂度与数据的位数线性相关,因此近似lgn,对应O(log(n))
9 Palindrome Number
Determine whether an integer is a palindrome. An integer is a palindrome when it reads the same backward as forward.
Example: 121: true, -121: false
Approach:
- python赖皮解法:
return str(x) == str(x)[::-1]
- 如果不用字符串的话,可以像第7题一样用数学方法翻转数字然后比较,不过这种方法无法处理大数溢出的问题
- 最好的解法是:只翻转一半的整数,然后和另一半比较(翻转方法与第7题类似)
- TC:O(lgn), SC(O(1))
13 Roman to Integer
Given a roman numeral, convert it to an integer. Input is guaranteed to be within the range from 1 to 3999.
(I-1, V-5, X-10, L-50, C-100, D-500, M-1000)
Note that I can be placed before V (5) and X (10) to make 4 and 9. The same as 40, 90, 400, 900. etc.
Approach:
- 从左往右判断,如果左边的字符对应的数大于或等于右边的,就把二者加起来,如果右边的大于左边的,就把左边的减去
- python解法:
dic = {'I':1,'V':5,'X':10,'L':50,'C':100,'D':500,'M':1000}
res = 0
for i in range(len(s)-1):
if dic[s[i]] < dic[s[i+1]]:
res = res - dic[s[i]]
else:
res = res + dic[s[i]]
return res + dic[s[-1]] # 负数索引就是从右往左数
14 Longest Common Prefix(前缀)
Write a function to find the longest common prefix string amongst an array of strings.
If there is no common prefix, return an empty string ""
All given inputs are in lowercase letters a-z.
Example: ["flower","flow","flight"] -> "fl", ["dog","racecar","car"] -> ""
Approach 1: Horizontal scanning
- 先找出前两个字符串的LCP,然后依次把得到的LCP与下一个字符串比较,得到新的LCP,直到比较完所有字符串或LCP为空
- LCP(S1…Sn)=LCP(LCP(LCP(S1,S2),S3),…Sn)
- TC: O(S), SC: O(1)
- 这里的S指所有字符串的字符数之和
Approach 2: Vertical scanning
- 竖着来,先比较所有字符串的第一位,再比较第二位,直到比完或出现差异
- TC: O(S), SC: O(1)
Approach 3: Divide and conquer(分治法)
- 利用这个性质:LCP(S1…Sn)=LCP(LCP(S1…Sk),LCP(Sk+1…Sn)),把问题不断向下分解成小问题,最后再合并结果
- TC: O(S), SC: O(mlogn)
Approach 4: Binary search
- 先找到最短的字符串,然后把它分成前后两半,进行二分前缀匹配
- TC: O(S⋅logn), SC: O(1)
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: "()"->true, "()[]{}"->true, "(]"->false, "([)]"->false, "{[]}"->true
Approach:
用一个栈就可以轻松实现
def isValid(s: str) -> bool:
symble = {" ":0, "(":1, "[":2, "{":3, ")":-1, "]":-2, "}":-3}
stack = 0
for i in s:
if symble[i] > 0:
stack = stack*10 + symble[i]
print(stack)
if symble[i] < 0:
stack += symble[i]
stack /= 10
print(stack)
if stack == 0:
return True
else:
return False
print(isValid(" ([( )[] ])"))
21 Merge Two Sorted Lists
Merge two sorted linked lists and return it as a new linked list. The new list should be made by splicing(插接) together the nodes of the first two lists.
Example: Input: 1->2->4, 1->3->4, Output: 1->1->2->3->4->4
Approach:
def mergeTwoLists1(self, l1, l2):
dummy = cur = ListNode(0)
while l1 and l2:
if l1.val < l2.val:
cur.next = l1
l1 = l1.next
else:
cur.next = l2
l2 = l2.next
cur = cur.next
cur.next = l1 or l2
return dummy.next
26 Remove Duplicates from Sorted Array
Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
Example:
Given nums = [1,1,2],
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
It doesn't matter what you leave beyond the returned length.
Approach:
- 双指针,开始时i在j前面
- 如果num[j]==num[i],那么j前进一格
- 如果num[j] != num[i],
- 那么i前进一格,并把j对应的值赋值到num[i]
27 Remove Element
Given an array nums and a value val, remove all instances of that value in-place and return the new length.
Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.
The order of elements can be changed. It doesn't matter what you leave beyond the new length.
Example:
Given nums = [3,2,2,3], val = 3,
Your function should return length = 2, with the first two elements of nums being 2.
Given nums = [0,1,2,2,3,0,4,2], val = 2,
Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4.
Approach:
- 双指针i,j,j在i后面
- 这时会有四种可能的情况:
- 如果j!=val且i==val,那么把j赋值给i,然后i,j各前进一格
- 如果jval且ival,那么j前进一格
- 如果j!=val且i!= val, 那么i,j各前进一格
- 如果j==val且i!=val,那么i,j各前进一格
优化:
- 双指针,ij初始时都指向同一个元素:
- 如果j!=val,那么ij各前进一格
- 如果j==val,那么j前进一格
28 Implement strStr()
Return the index of the first occurrence of needle in haystack, or -1 if needle is not part of haystack.
Example:
Input: haystack = "hello", needle = "ll"
Output: 2
Approach:
- 双指针ij,i慢j快:
- 如果j等于needle[k] (k默认为0),那么j前进,k前进
- 如果j不等于needle[k],那么i前进,j=i,k=0
35 Search Insert Position
Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.
Example:
Input: [1,3,5,6], 5
Output: 2
Input: [1,3,5,6], 2
Output: 1
Approach:
- 遍历数组,判断:
- 如果i==val,输出i
- 如果i<val<=i+1,输出i+1
- 如果遍历完了还没找到,那么输出length(arr)
38 Count and Say
题目没看懂。。。LeetCode-Count and Say
53 Maximum Subarray
Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.
Example:
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.
Approach
def maxSubArray(self, nums: List[int]) -> int:
globalsum,localsum=0,0
if max(nums)<0:
return max(nums)
for i in nums:
localsum=max(0,localsum+i)
globalsum=max(localsum,globalsum)
return globalsum
Go over the array from left to right. For each element (with index n) of the array calculate the maximum contiguous subarray sum, with the condition that the contiguous subarray contains this element n. This can be done using DP approach by keeping track of only one number "prev". When moving from index n to index n+1 we decide on whether to include the "prev" we calculated for n, or just take the single n+1th element. This simply depends on whether "prev" for n was negative or not. If it was negative, we don't want to append the associated array to n+1'st element. In which case the best "prev" for the subarray from index 0 ending and including n+1'st element, is prev=n+1 (corresponding to array of just one element, the n+1'st one). If "prev" for n was positive, we would want to append it to n+1'st element.
While doing this forward pass also try to save the largest prev in the r, which then will be returned.
class Solution(object):
def maxSubArray(self, nums):
if len(nums) == 0:
return 0
prev = nums[0]
r = nums[0]
for n in nums[1:]:
if prev > 0:
prev += n
else:
prev = n
if prev > r:
r = prev
return r