在线笔试题
1、移动零
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序
示例
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:必须在原数组上操作,不能拷贝额外的数组。尽量减少操作次数
方法一 :覆盖法
定义两个指针 i,j 如果前面指针不等于0则后面的值覆盖前面的值,最后再把 0 补回去
def moveZeroes(self, nums: List[int]) -> None:
j = 0
for i in range(len(nums)):
if nums[i] !=0:
nums[j] = nums[i]
j+=1
while j< len(nums):
nums[j] = 0
j+=1
方法二:对方法一进行优化,但本质依然是两个指针
void moveZeroes(vector<int>& nums) {
int i = 0;
int count = 0;
for(;i<nums.size();++i){
if(nums[i] !=0){
swap(nums[count++],nums[i]);
}
}
}
方法三:python 版本,利用删除和尾加
def moveZeroes(self, nums):
n = nums.count(0)
for i in range(n):
nums.remove(0)
nums.append(0)
2、寻找重复数
给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 n 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。
示例 1:
输入: [1,3,4,2,2]
输出: 2
示例 2:
输入: [3,1,3,4,2]
输出: 3
说明:
(1)不能更改原数组(假设数组是只读的)
(2)只能使用额外的 O(1) 的空间
(3)时间复杂度小于 O(n2)
(4)数组中只有一个重复的数字,但它可能不止重复出现一次
方法一:首先利用库函数进行排序,然后利用判断前一个数字和后一个是否相等,如果相等则返回它
def findDuplicate(self, nums: List[int]) -> int:
nums.sort()
n = len(nums)
for i in range(1,n):
if nums[i] == nums[i-1]:
return nums[i]
方法二:直接利用 sum 求和函数和 set 去重函数
return (sum(nums)-sum(set(nums))) // (len(nums)-len(set(nums)))
方法三:可以用 O(N) 的时间复杂度完成
思路:遍历数组,如果发现下标对应的数据和当前数据相等,则返回这个数字,如果不相等,则把该数字和它对应的下标数字进行交换.
def findDuplicate(self, nums: List[int]) -> int:
n = len(nums)
i = 0
while i<n:
if nums[i] != i:
if nums[nums[i]] == nums[i]:
return nums[i]
else:
nums[nums[i]], nums[i] = nums[i], nums[nums[i]]
else:
i += 1
方法四:始终和第一个数字进行交换判断,因为数组中没有 0 元素,所以不用害怕在 0 的位置上有 0 元素
int findDuplicate(vector<int>& nums) {
while(1){
int num = nums[0];
if(nums[num]==num){
return num;
}
nums[