leetcode283. 移动零,
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12]
输出: [1,3,12,0,0]
示例 2:
输入: nums = [0]
输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
题目描述
给定一个数组 nums
,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。
算法分析
这个问题可以通过双指针法来解决。我们使用两个指针,一个用于跟踪下一个非零元素应该放置的位置(i
),另一个用于遍历数组(j
)。当 j
指向的元素非零时,我们将它与 i
指向的元素交换,并递增 i
。这样,所有非零元素都会被移动到数组的开头,而 i
之后的元素都是零。
算法步骤
- 初始化两个指针
i
和j
,都设置为 0。 - 使用
j
遍历数组nums
。 - 当
nums[j]
非 0 时,交换nums[i]
和nums[j]
,并递增i
。 - 继续遍历直到
j
到达数组末尾。 - 此时,
i
之后的所有元素都是 0。
算法流程
具体代码
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int i=0,j=0;
while(j<nums.size())
{
if(nums[j])
{
swap(nums[i],nums[j]);
i++;
}
j++;
}
}
};
算法分析
复杂度分析
- 时间复杂度:O(n),其中 n 是数组的长度。我们只需要遍历数组一次。
- 空间复杂度:O(1),我们只需要常数级别的额外空间来存储指针。
易错点
- 在交换元素时,确保正确地交换
nums[i]
和nums[j]
。 - 注意不要在
nums[j]
为 0 时递增i
。
注意事项
- 确保在遍历数组时不要超出数组的边界。
- 在交换元素时,确保不会覆盖任何元素。
相似题目
题目 | 链接 |
---|---|
移动元素 | https://leetcode.com/problems/move-element-to-end/ |
删除元素 | https://leetcode.com/problems/remove-element/ |
荷兰国旗问题 | https://leetcode.com/problems/sort-colors/ |