283. Move Zeroes
题目解释:给出一个nums数组,写一个方法将所有的0移动到数组的末尾,但是不改变原来数组中其他元素的顺序。
Example:
Input:
[0,1,0,3,12]
Output:
[1,3,12,0,0]
Note:
- 你必须是采用就地调换,空间复杂度为O(1)
- 最小话元素的操作。
题目分析:首先,不考虑其他注意事项,我们可以申请一个长度和输入的数组长度相等的数组,当遇到非零元素时,我们可以将元素追加到辅助数组中,最后到辅助数组的末尾增加元素0,使其长度和原始输入数组的长度相等。这是最简单的解题方式。
对于这个题目,其实已经解决了,但是题目是要求的我们空间复杂度为O(1),即还需要进行一定的优化。那么怎么才能将空间复杂度优化为O(1)呢?我们可以借助于两个指针,第一个指针是指向下一个0元素,然后一个工作指针,其实状态,假设两个指针i,j分别指向数组的头部,以上面的示例为例,i为工作指针,j为指向0的指针,第一个元素为0,那么i++,然后到达第二个元素,为1,交换a[i]和a[j]的位置,并且j++,遇到下一个0元素时,将指针j指向0,重复操作即可。
class Solution(object):
def moveZeroes(self, nums):
"""
:type nums: List[int]
:rtype: None Do not return anything, modify nums in-place instead.
"""
j = 0
for i in range(len(nums)):
# 当前元素不为0时
if nums[i] != 0:
temp = nums[i]
nums[i] = 0
nums[j] = temp
# 记录0元素的角标
j += 1
287. Find the Duplicate Number
题目解释:给出一个n+1长度的整数数组,其中数组中的每个元素都是1~n之间,这样很容易发现有重复的元素存在,假设只有一个重复的元素,找到这个重复的元素。
Example 1:
Input:
[1,3,4,2,2]
Output: 2
Example 2:
Input: [3,1,3,4,2]
Output: 3
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.
题目分析:在看到这个题目的时候,很巧,今天也是刚刚完成了同样类型的一道题(leetcode 41. First Missing Positive),跟这道题是异曲同工之妙。总体的思路也是一样的。
思路1:我们大体的思路就是;先遍历一遍数组,使其相应的元素应该出现在确定的位置(即第i个元素的值应该是i+1,否则这个值就是重复的元素)。这个是基于交换的思路,时间复杂度为O(n),空间复杂度为O(1),但是我们在操作的过程中改变了元素的位置,这违反了第一个要求(第一个要求为只读)。
思路2:最简单的做法就是借助于一个set,先将元素往set里面加,当发现遍历到的元素在set中,那么返回这个元素;否则将元素加入到set(用set的原因是因为set查找元素的效率为0(1)),但是这是不满足空间复杂度的要求,需要再次进行优化
def findDuplicate(self,nums):
"""
采用set来解决,时间复杂度和空间复杂度均为O(n)
:param nums:
:return:
"""
seen=set()
for num in nums:
if num in seen:
return num
seen.add(num)
思路3:这种思路感觉就很神奇了,这是借助于我们判断链表是否有环这个条件去做的,在数组中我们也可以进行类似操作,给定一个快指针,一个慢指针,在这个问题中,必然存在重复元素,那么他们必然就会相遇。
ps:主要是将这个问题抽象成环的话,是很难想的。总结如下:https://blog.csdn.net/sir_TI/article/details/89494500
class Solution(object):
def findDuplicate(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
# 初始化快慢指针
slow = nums[0]
fast = nums[nums[0]]
# 找到环的连接点
while slow != fast:
fast = nums[nums[fast]]
slow = nums[slow]
# 将快指针置为0
fast = 0
# 快指针、慢指针每次都是移动一步
while slow != fast:
fast = nums[fast]
slow = nums[slow]
return fast
总结
2019/5/31 偷了两天懒,接下来就把偷懒的要做的事补起来
PS:一时偷懒一时爽,一直偷懒一直爽.......