283. Move Zeroes【easy】
283. Move Zeroes【easy】
Given an array nums, write a function to move all 0's to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
Note:
- You must do this in-place without making a copy of the array.
- Minimize the total number of operations.
Credits:
Special thanks to @jianchao.li.fighter for adding this problem and creating all test cases.
解法一:
class Solution {
public:
void moveZeroes(vector<int>& nums) {
int i = , j = ;
while (i < nums.size()) {
if (nums[i] != ) {
nums[j++] = nums[i++];
}
else
{
++i;
}
}
while (j < nums.size()) {
nums[j++] = ;
}
}
};
双指针
解法二:
This is a 2 pointer approach. The fast pointer which is denoted by variable "cur" does the job of processing new elements. If the newly found element is not a 0, we record it just after the last found non-0 element. The position of last found non-0 element is denoted by the slow pointer "lastNonZeroFoundAt" variable. As we keep finding new non-0 elements, we just overwrite them at the "lastNonZeroFoundAt + 1" 'th index. This overwrite will not result in any loss of data because we already processed what was there(if it were non-0,it already is now written at it's corresponding index,or if it were 0 it will be handled later in time).
After the "cur" index reaches the end of array, we now know that all the non-0 elements have been moved to beginning of array in their original order. Now comes the time to fulfil other requirement, "Move all 0's to the end". We now simply need to fill all the indexes after the "lastNonZeroFoundAt" index with 0.
void moveZeroes(vector<int>& nums) {
int lastNonZeroFoundAt = ;
// If the current element is not 0, then we need to
// append it just in front of last non 0 element we found.
for (int i = ; i < nums.size(); i++) {
if (nums[i] != ) {
nums[lastNonZeroFoundAt++] = nums[i];
}
}
// After we have finished processing new elements,
// all the non-zero elements are already at beginning of array.
// We just need to fill remaining array with 0's.
for (int i = lastNonZeroFoundAt; i < nums.size(); i++) {
nums[i] = ;
}
}
Complexity Analysis
Space Complexity : O(1)O(1). Only constant space is used.
Time Complexity: O(n)O(n). However, the total number of operations are still sub-optimal. The total operations (array writes) that code does is nn (Total number of elements).
解法三:
The total number of operations of the previous approach is sub-optimal. For example, the array which has all (except last) leading zeroes: [0, 0, 0, ..., 0, 1].How many write operations to the array? For the previous approach, it writes 0's n-1n−1 times, which is not necessary. We could have instead written just once. How? ..... By only fixing the non-0 element,i.e., 1.
The optimal approach is again a subtle extension of above solution. A simple realization is if the current element is non-0, its' correct position can at best be it's current position or a position earlier. If it's the latter one, the current position will be eventually occupied by a non-0 ,or a 0, which lies at a index greater than 'cur' index. We fill the current position by 0 right away,so that unlike the previous solution, we don't need to come back here in next iteration.
In other words, the code will maintain the following invariant:
All elements before the slow pointer (lastNonZeroFoundAt) are non-zeroes.
All elements between the current and slow pointer are zeroes.
Therefore, when we encounter a non-zero element, we need to swap elements pointed by current and slow pointer, then advance both pointers. If it's zero element, we just advance current pointer.
With this invariant in-place, it's easy to see that the algorithm will work.
void moveZeroes(vector<int>& nums) {
for (int lastNonZeroFoundAt = , cur = ; cur < nums.size(); cur++) {
if (nums[cur] != ) {
swap(nums[lastNonZeroFoundAt++], nums[cur]);
}
}
}
Complexity Analysis
Space Complexity : O(1)O(1). Only constant space is used.
Time Complexity: O(n)O(n). However, the total number of operations are optimal. The total operations (array writes) that code does is Number of non-0 elements.This gives us a much better best-case (when most of the elements are 0) complexity than last solution. However, the worst-case (when all elements are non-0) complexity for both the algorithms is same.
上面解法仍有优化空间,对于下标不同的时候才交换
class Solution {
public:
void moveZeroes(vector<int>& nums) {
for (int i = , j = ; i < nums.size(); ++i) {
if (nums[i] != ) {
if (i != j) {
swap(nums[j], nums[i]);
}
++j;
}
}
}
};
解法二、三均参考自solution
283. Move Zeroes【easy】的更多相关文章
- 【leetcode】283. Move Zeroes
problem 283. Move Zeroes solution 先把非零元素移到数组前面,其余补零即可. class Solution { public: void moveZeroes(vect ...
- LeetCode Javascript实现 283. Move Zeroes 349. Intersection of Two Arrays 237. Delete Node in a Linked List
283. Move Zeroes var moveZeroes = function(nums) { var num1=0,num2=1; while(num1!=num2){ nums.forEac ...
- 27. Remove Element【easy】
27. Remove Element[easy] Given an array and a value, remove all instances of that value in place and ...
- 657. Judge Route Circle【easy】
657. Judge Route Circle[easy] Initially, there is a Robot at position (0, 0). Given a sequence of it ...
- 557. Reverse Words in a String III【easy】
557. Reverse Words in a String III[easy] Given a string, you need to reverse the order of characters ...
- 283. Move Zeroes(C++)
283. Move Zeroes Given an array nums, write a function to move all 0's to the end of it while mainta ...
- 170. Two Sum III - Data structure design【easy】
170. Two Sum III - Data structure design[easy] Design and implement a TwoSum class. It should suppor ...
- 160. Intersection of Two Linked Lists【easy】
160. Intersection of Two Linked Lists[easy] Write a program to find the node at which the intersecti ...
- 206. Reverse Linked List【easy】
206. Reverse Linked List[easy] Reverse a singly linked list. Hint: A linked list can be reversed eit ...
随机推荐
- POJ 2975 Nim(博弈论)
[题目链接] http://poj.org/problem?id=2975 [题目大意] 问在传统的nim游戏中先手必胜策略的数量 [题解] 设sg=a1^a1^a3^a4^………^an,当sg为0时 ...
- 【贪心】Codeforces Round #401 (Div. 2) D. Cloud of Hashtags
从后向前枚举字符串,然后从左向右枚举位. 如果该串的某位比之前的串的该位小,那么将之前的那串截断. 如果该串的某位比之前的串的该位大,那么之前那串可以直接保留全长度. 具体看代码. #include& ...
- python3开发进阶-Django框架的ORM常用字段和参数
阅读目录 常用字段 字段合集 自定义字段 字段参数 关系参数 多对多的关联关系的三种方式 一.常用字段 AutoField int自增列,必须填入参数 primary_key=True.当model中 ...
- 语言基础之description方法
1.description方法的一般用处 1: // 指针变量的地址 2: NSLog(@"%p", &p); 3: // 对象的地址 4: NSLog(@"%p ...
- 使用GIT时排除NuGet的packages文件夹
这段时间一直在用GIT做本地自己写的程序的源码管理工具,在使用的过程中发现了一个问题:Git往往会把NuGet的packages文件夹作为项目的一部分给添加进来了.网上搜了一下,原因是GIT只是和文件 ...
- ARM“庖丁解牛”之存储器管理单元MMU
转:http://blog.sina.com.cn/s/blog_a07635070101bcbt.html 最近笔者详细地学习了由杜春雷老师编写的<ARM体系结构与编程>.对ARM存储管 ...
- mq
同时每个 Broker 与NameServer 集群中的所有节点建立长连接,定时注册 Topic 信息到所有 NameServer 中. Producer 与 NameServer 集群中的其中一个节 ...
- 如何判断一个请求是不是ajax请求
原文:http://blog.csdn.net/easy_is_good/article/details/53609057 public boolean isAjaxRequest(HttpServl ...
- Shiro+SpringMVC 实现更安全的登录(加密匹配&登录失败超次数锁定帐号)
原文:http://blog.csdn.net/wlwlwlwl015/article/details/48518003 前言 初学shiro,shiro提供了一系列安全相关的解决方案,根据官方的介绍 ...
- 纯C实现面向对象
#include <stdio.h> #include <stdlib.h> //接口 #ifndef Interface #define Interface struct # ...