大家好,我就是那个在B站讲算法的「华南溜达虎」。
最近这两天vivo的秋招offer开始陆续发放了,看网上不少同学表示不太满意,嫌给的太少了。还有同学说自己坐火车跑去面试,最后给的价格太侮辱人了,心疼来回的车票钱。
我也去搜了一下,想看看给的到底是有多低,才有这么多同学吐槽。看完感觉跟比亚迪比还是强点,没有其他offer的话,可以做为一个保底offer。
25届秋招已经开始了,我组织了一个秋招群,大家可以交流学习心得、面试经验,分享工作机会,有啥问题也可以在群里咨询。在群里我整理了一百多家已经启动秋招企业的文档,以及投递入口,每天都会更新,大家只要按照这个文档海投就可以了。
大家互帮互助相信一定可以拿下秋招!计算机相关专业的同学可以 点击底部的「阅读原文」 加群。
言归正传,今天我们来分享一道高频面试题「移动零」。
题目描述
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
举个例子:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
思路解析
题目要求对数组原地操作,也就是要求空间复杂度位O(1)。
我们可以遍历一遍数组统计出非零的个数m
,然后再遍历一遍数组把非零的元素依次覆盖数组的前m
个位置,最后把剩下的n-m
个位置置为0
。这样我们需要遍历两遍数组,时间复杂度也是O(1)。
下面我再介绍一种只遍历一遍数组的双指针解法,整体的思路类似快速排序。
定义两个指针,left = 0, right = 0
。
如果nums[right] == 0,right指针就往右移一步。 如果nums[right] != 0,就交换nums[left]和nums[right]的值,left和right同时向右移一步。
上述步骤保证了left != right
时,left
始终指向为零的元素,一旦right
指向了非零元素,left
和right
就交换指向的元素。
下面我们给出c++和python两种代码实现。
c++代码
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int left = 0;
for (int right = 0; right < nums.size(); ++right) {
//right指向元素不为0时,跟left交换指向的元素
//如果left != right,left一定指向为零的元素
//就算left == right,交换一下元素也没关系
if (nums[right]) {
//交换left和right指向的元素
int temp = nums[right];
nums[right] = nums[left];
nums[left] = temp;
++left;
}
}
}
};
python代码
class Solution:
def moveZeroes(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
left = 0
for right in range(len(nums)):
#right指向元素不为0时,跟left交换指向的元素
#如果left != right,left一定指向为零的元素
#就算left == right,交换一下元素也没关系
if nums[right] != 0:
#交换left和right指向的元素
nums[left], nums[right] = nums[right], nums[left]
left += 1
复杂度分析
时间复杂度: O(n),其中n
为nums
的长度。
空间复杂度: O(1)。
号外
经常使用leetcode会员的同学可以使用我的优惠通道啦!
https://leetcode.cn/premium/?promoChannel=ldtiger ,年度会员有效期比官网多俩月,季度会员有效期比官网多两个星期,还有专属福利,需要的读者朋友可以找我了解。
今天的分享就到这里,希望大家能有所收获!