总结了几道leetcode中常见的同类型题
到底是谁重复了
到底是谁丢了
大合集!Come on!
Leetcode 136 SingleNumber(无序,所有数都重复了两遍,只有一个数重复了一遍。很有特点的题,用异或方法解题)
问题:Given an array of integers, every element appears twice except for one. Find that single one.
Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?
public class Solution {
public int singleNumber(int[] nums) {
int result=0;
for(int i=0;i<nums.length;i++) {
result^=nums[i];
}
return result;
}
}
看完这个做法以后如醍醐灌顶,豁然开朗
Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.
解法一:
看到一个非常漂亮的答案:
class Solution(object):
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
return len(nums) > len(set(nums))
利用python数据结构set去重的特性,漂亮!
42ms,打败了97.47%的运行时间。
解法二:(这个解法实在是太笨了,因我根本不需要排序)
我想这道题本身考的不是python解法一NB的功能
所以我自己写了个通用的算法:
先将list按增序排序
遍历从第1个数字到最后一个数字,比较当前数字与其前一个是否相等。如果相等则证明有重复
如果遍历结束都没有重复则证明该list没有重复
class Solution(object):
def containsDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: bool
"""
nums=sorted(nums)
for i in range(1,len(nums)):
if nums[i] == nums[i-1]:
return True
return False
#52ms,打败了54%的用户
Contains Duplicate II(无序,返回是否有两个数字的间距超过k)
Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the absolute difference between i and j is at most k.
这题不容易读明白,它意思是:找一个数组中是否有重复的数字,且这两个数字的index间距不能超过k
比Contains Duplicate I的难点在于:
不能先对数组排序了,否则会改变index就不符合题意了。
解法如下:
class Solution(object):
def containsNearbyDuplicate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
dic = {}
for i, v in enumerate(nums):
if v in dic and i - dic[v] <= k:
return True
dic[v] = i
return False
这个方法除去k的限制,就是说用dict这种思想同样适合于Contains Duplicate I
52ms,打败了60%
这也是我第一次接触enumerate()这个函数,解法二中 i代表index,v代表value, for i , v in enumerate(nums)是把nums里的index和value遍历出来。当同时需要index和value时用enumerate()函数写比较方便
以上两道都是初级题目,下面是中级题目:
https://leetcode.com/problems/contains-duplicate-iii/discuss/
后续还要做
448. Find All Numbers Disappeared in an Array(无序,有的元素出现了两次,其余出现一次,no extra space,返回所有缺失的数)
Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[5,6]
难点:要求 O(n)运行时间,没有多余的空间
解题思路:
把拜访过的脚标对应的nums[i]记为负数
这样没拜访过的(就是寻找的缺失值)就是正数,返回出来
class Solution:
def findDisappearedNumbers(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
nums = [0] + nums
for i in range(len(nums)):
index = abs(nums[i])
nums[index] = -abs(nums[index])
return [i for i in range(len(nums)) if nums[i] > 0]
342ms,只打败了23.65%的python3答案
看到一个更好的218ms的方法:
class Solution:
def findDisappearedNumbers(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
return list({i for i in range(1, len(nums)+1)} - set(nums))
442. Find All Duplicates in an Array(无序,有的数出现了两次,有的数出现了一次,no extra space,返回所有的出现两次的数)
解题方法与448类似
Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements that appear twice in this array.
Could you do it without extra space and in O(n) runtime?
Example:
Input:
[4,3,2,7,8,2,3,1]
Output:
[2,3]
class Solution:
def findDuplicates(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
result = []
for x in nums:
if nums[abs(x)-1] < 0:
result.append(abs(x))
else:
nums[abs(x)-1] = -1*nums[abs(x)-1]
return result
276ms,打败67.55%
还找到了要给212ms打败绝大多数python3答案的
但是这个答案不符合题意的without extra space,但是我发现它真的really叹为观止啊! s.add(num)这个操作我试了一下,永远是Fasle
class Solution:
def findDuplicates(self, nums):
"""
:type nums: List[int]
:rtype: List[int]
"""
s = set()
return [
num for num in nums if num in s or s.add(num)
]
268. Missing Number(0到n个数,无序,丢了一个数,找到它)
Given an array containing n distinct numbers taken from 0, 1, 2, ..., n
, find the one that is missing from the array.
Example 1
Input: [3,0,1]
Output: 2
Example 2
Input: [9,6,4,2,3,5,7,0,1]
Output: 8
我最初竟然想用二叉搜索去解,问题是找到mid以后,不知道是应该往mid的左边找还是mid的右边找,总不能两边都找那不成暴力破解了,所以还是直接写暴力破解吧(53ms)。
class Solution(object):
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
num_set = set(nums)
n = len(nums) + 1
for number in range(n):
if number not in num_set:
return number
时间复杂度:O(n)
这个方法其实就是暴力破解了,但是发现一个问题很不明白:
就是如果把num_set=set(nums)这句话去掉,改成if number not in nums:就会超时!
换言之,set(nums)比不set节省时间!这是为什么呢?
Solution里管这个叫HashSet, set 为什么能达到Hash的效果呢?
看了一下解法里最快36ms的是这个NB的数学解法,但这不是普遍的解法,秀一下技巧吧:
这个解法叫高斯Formula: i=0∑ni=2n(n+1)
class Solution(object):
def missingNumber(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
n = len(nums)
return (1 + n) * n / 2 - sum(nums)
总结:
1.本来无序的数组不要排序!排序就已经输在了起跑线上!
2.用python3中的set()往往是效率比较高的solution