1. 删除排序数组中的重复项
给你一个有序数组 nums,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组 并在使用 O(1) 额外空间的条件下完成。
nums = [1,1, 3, 4, 5, 7, 9, 9]
# 速度慢
def remove_repeat(nums):
for i in range(len(nums)-1, 0, -1):
if nums[i] == nums[i-1]:
del nums[i]
return len(nums)
def remove_index(nums):
if not nums:
return 0
p, q, n = 0, 1, len(nums)
while q < n:
if nums[p] == nums[q]:
q += 1
else:
nums[p+1] = nums[q]
q += 1
p += 1
return len(nums[:p+1])
解题思路: 双指针
首先注意数组是有序的,那么重复的元素一定会相邻。要求删除重复元素,实际上就是将不重复的元素移到数组的左侧。
考虑用 2 个指针,一个在前记作 p,一个在后记作 q,算法流程如下:
比较 p 和 q 位置的元素是否相等;如果相等,q 后移 1 位;如果不相等,将 q 位置的元素复制到 p+1 位置上,p 后移一位,q 后移 1 位;
重复上述过程,直到 q 等于数组长度(n)。最后返回nums[: p + 1],即为新数组长度。
2. 数组旋转
给定一个数组,将数组中的元素向右移动 k 个位置,其中 k 是非负数。
进阶:
尽可能想出更多的解决方案,至少有三种不同的方法可以解决这个问题。
使用空间复杂度为 O(1) 的 原地 算法解决这个问题
进阶版:
nums = [1, 3, 6, 7, 9, 12]
k = 4
def reverse_list(nums, k):
nums[: ] = (nums[i] for i in range(-(k % len(nums)), len(nums) - k % len(nums)))
return nums
reverse_list(nums, 6)
糙版:
def reverse_list(nums, k):
k = k % len(nums)
# nums[:] = nums[len(nums)-k:] + nums[:len(nums)-k]
nums[:] = nums[:-k] + nums[-k:]
return nums
def reverse_list(nums, k):
while k != 0:
nums.insert(0, nums.pop())
k-=1
return nums
解题思路:
1. 数组翻转
当我们将数组的元素向右移动 k 次后,尾部 k mod n 个元素会移动至数组头部,其余元素向后移动 k mod n 个位置。
该方法为数组的翻转:我们可以先将所有元素翻转,这样尾部的 k mod n 个元素就被移至数组头部,然后我们再翻转 [0, (k mod n)-1]区间的元素和 [k mod n, n-1]区间的元素
例子如下:
nums = [1, 3, 6, 7, 9, 12] | |
k = 4 n = len(nums) = 6 | k mod n = 4 |
原始数据 | [1, 3, 6, 7, 9, 12] |
翻后的数据 | [12, 9, 7, 6, 3,1] |
翻转[0, (k mod n) -1](即[0~3] | [6, 7, 9, 12, 3,1] |
在翻转[k mod n, n-1](即[4~5]) | [6, 7, 9, 12, 1, 3] |
3. 判断是否存在重复元素
给定一个整数数组,判断是否存在重复元素。
如果存在一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false
nums =[1, 3, 5, 6, 7, 1, 3]
def verfi(nums):
return len(nums) != len(set(nums))
def verfi(nums):
numm = sorted(nums)
tag = False
for i in range(0, len(numm)):
if numm[i] == numm[i-1]:
tag = True
return tag
verfi(nums)
4. 找出只出现一次的数字
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
注意: 列表中不重复的数字只有一个
nums = [1, 2, 1, 3, 4, 3, 4]
def once_number(nums):
d = set()
for i in nums:
if i in d:
d.remove(i)
continue
d.add(i)
return d.pop()
# python 运算符
# 按位异或运算符:当两对应的二进位相同时,结果为0
def once_number(nums):
a = 0
for i in nums:
a = a^i
return a
def once_number(nums):
import functools
return functools.reduce(int.__xor__,nums)
once_number(nums)
"""
2
"""