要求

将所有的0,移动到vector的后面
比如; [1,3,0,12,5] -> [1,3,12,5,0]

实现

第一版程序,时间、空间复杂度都是O(n)

 1 #include<iostream>
2 #include<vector>
3
4 using namespace std;
5
6 class Solution{
7 public:
8 void moveZeros(vector<int>& nums){
9 vector<int> nonZeroElements;
10 for( int i = 0 ; i < nums.size() ; i ++ )
11 if( nums[i] )
12 nonZeroElements.push_back(nums[i]);
13 for( int i = 0 ; i < nonZeroElements.size() ; i ++ )
14 nums[i] = nonZeroElements[i];
15 for( int i = nonZeroElements.size() ; i < nums.size() ; i ++ )
16 nums[i] = 0;
17 }
18 };
19
20 int main(){
21 int arr[] = {0, 1, 0, 3, 12};
22 vector<int> vec(arr, arr + sizeof(arr)/sizeof(int) );
23 Solution().moveZeros( vec );
24 for( int i = 0 ; i < vec.size() ; i ++ )
25 cout<<vec[i]<<" ";
26 cout<<endl;
27 }

优化后,空间复杂度O(1)

 1 class Solution{
2 public:
3 // 索引
4 void moveZeros(vector<int>& nums){
5 int k = 0;
6 // 遍历到第i个元素后,保证[0...i)中所有非0元素
7 // 均按顺序排列在[0...k)中
8 for( int i = 0 ; i < nums.size() ; i ++ )
9 if( nums[i] )
10 nums[k++] = nums[i];
11 // 将[k...n]赋值为0
12 for( int i = k ; i < nums.size() ; i ++ )
13 nums[i] = 0;
14 }
15 }

利用交换,提高效率

1 void moveZeros1(vector<int>& nums){
2 int k = 0;
3 for( int i = 0 ; i < nums.size() ; i ++ )
4 if( nums[i] )
5 swap( nums[k++] , nums[i] );
6 }

增加判断,提高非零元素较多时的效率

 1 void moveZeros1(vector<int>& nums){
2 int k = 0;
3 for( int i = 0 ; i < nums.size() ; i ++ )
4 if( nums[i] )
5 // 指向同一个元素时不交换
6 if( i != k )
7 swap( nums[k++] , nums[i] );
8 else // i == k
9 k++;
10 }

>> 1 3 2 12 0 0

要点

  • k始终指向第一个0
  • 每次交换后k后移

总结

  • 算法设计是一个过程
  • 索引非常重要,顺序、选择、循环、交换都是索引的操作而已,每个索引都必须知道自己要去做什么
  • 一开始的设计可以是粗粒度的,但不代表不对,只是效率低(时间、空间)
  • 发现问题,解决问题,逐步优化
  • 不要一开始就陷入测试用例中(先想好怎么操作球,而不去看球上的数字)
  • 语法是次要的,思路是主要的,语言的底层都是系统命令
  • 设计算法的步骤:思路-->实现-->优化
  • 如果看到理解不了思路的复杂算法,不要硬想,有可能是考虑了某种因素的优化版本,先学习容易理解的版本,了解其不足,想想如何在其基础上优化,复杂版本自然就懂了
  • 算法就是做一件事的流程,进一步抽象,由三部分组成
    • 手:变量,索引,指针
    • 物品:数据
    • 工具:容器,数组,栈,内存
  • 设计一个算法,就是要想清楚怎么用手借助工具去操作物品,即指针如何利用内存操作数据
  • 操作的方式是循环(递归),即在n-1步正确为前提,证明n步正确
  • 数据结构作为算法的工具,封装了规则,而规则的实现又要依赖于算法
  • 数据结构通常以类的形式实现,类中的数据不是真实的数据,而是“虚拟”出来的待操作数据,类中的方法就是算法

[刷题] 283 Move Zeros的更多相关文章

  1. LeetCode 283 Move Zeros

    Problem: Given an array nums, write a function to move all 0's to the end of it while maintaining th ...

  2. leetcode 283 Move Zeros; 27 Remove Elements; 26 Remove Duplicated from Sorted Array;

    ,,,,}; //把数组的值赋给vector vector<int> vec(arr, arr+sizeof(arr)/sizeof(int)); 解法一: 时间复杂度O(n) 空间复杂度 ...

  3. LeetCode刷题记录(python3)

    由于之前对算法题接触不多,因此暂时只做easy和medium难度的题. 看完了<算法(第四版)>后重新开始刷LeetCode了,这次决定按topic来刷题,有一个大致的方向.有些题不止包含 ...

  4. leetcode 刷题记录(java)-持续更新

    最新更新时间 11:22:29 8. String to Integer (atoi) public static int myAtoi(String str) { // 1字符串非空判断 " ...

  5. C#LeetCode刷题-双指针

    双指针篇 # 题名 刷题 通过率 难度 3 无重复字符的最长子串   24.5% 中等 11 盛最多水的容器   43.5% 中等 15 三数之和   16.1% 中等 16 最接近的三数之和   3 ...

  6. C#LeetCode刷题-数组

    数组篇 # 题名 刷题 通过率 难度 1 两数之和 C#LeetCode刷题之#1-两数之和(Two Sum) 43.1% 简单 4 两个排序数组的中位数 C#LeetCode刷题之#4-两个排序数组 ...

  7. 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 ...

  8. 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 ...

  9. [LeetCode] 系统刷题5_Dynamic Programming

    Dynamic Programming 实际上是[LeetCode] 系统刷题4_Binary Tree & Divide and Conquer的基础上,加上记忆化的过程.就是说,如果这个题 ...

随机推荐

  1. Docker安装完成后启动报错:Failed to start Docker Application Container Engine

    报错如下:显示没有启动 先关闭防火墙:防火墙关闭指令请看  <a href="Linux防火墙篇">https://www.cnblogs.com/szx666/p/1 ...

  2. 翻译:《实用的Python编程》07_05_Decorated_methods

    目录 | 上一节 (7.4 装饰器) | 下一节 (8 测试和调试) 7.5 装饰方法 本节讨论一些与方法定义结合使用的内置装饰器. 预定义的装饰器 在类定义中,有许多预定义的装饰器用于指定特殊类型的 ...

  3. 使用SignalR ASP.NET Core来简单实现一个后台实时推送数据给Echarts展示图表的功能

    什么是 SignalR ASP.NET Core ASP.NET Core SignalR 是一种开放源代码库,可简化将实时 web 功能添加到应用程序的功能. 实时 web 功能使服务器端代码可以立 ...

  4. 动态的创建Class对象方法及调用方式性能分析

    有了Class对象,能做什么? 创建类的对象:调用Class对象的newInstance()方法 类必须有一个无参数的构造器. 类的构造器的访问权限需要足够. 思考?没有无参的构造器就不能创建对象吗? ...

  5. Floyd算法C++实现与模板题应用

    简介 Floyd算法算是最简单的算法,没有之一. 其状态转移方程如下map[i , j] =min{ map[i , k] + map[k , j] , map[i , j] }: map[i , j ...

  6. Borrowers UVA - 230

      I mean your borrowers of books - those mutilators of collections, spoilers of the symmetry of shel ...

  7. C++ 内存模型之单独编译

    单独编译得意义 将一个程序分成多个文件按保存,如果过对程序修改,找到要修改得文件进行修改后重新编译,则可以之重新编译该文件,然后后将他于其他文件得编译版本链接,是的大程序得管理更加高效便捷. 将单文件 ...

  8. linux中mysql连接不上,服务启动失败等问题解决

    confluence问题解决方式 1)针对confluence访问页面报500与连接失败等问题 首先我们登陆部署confluence的服器 10.15.4.115 2)重启mysql服务,发现重启失败 ...

  9. 所谓 ICMP,不过将军与士卒而已

    什么是 ICMP 协议 关于这点我们在 IP 协议那篇文章中提过一嘴,IP 协议作为一种提供不可靠数据交付的网络层协议,在传输的过程中,其 IP 数据报可能会发生丢失.重复.延迟和乱序等各种情况, 但 ...

  10. 0-0 Linux安装在VMvare虚拟机上

    一.安装VMware虚拟机: 双击, 上面一步会提示你输入密钥,你只要双击这个,复制里面的一串码粘贴进去就可以. 点击完成,至此VM虚拟机安装完成. 二.在VMvare虚拟机上安装centos. 1. ...