[刷题] 283 Move Zeros

要求

将所有的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步正确
  • 数据结构作为算法的工具,封装了规则,而规则的实现又要依赖于算法
  • 数据结构通常以类的形式实现,类中的数据不是真实的数据,而是“虚拟”出来的待操作数据,类中的方法就是算法
posted @ 2020-03-05 00:23  cxc1357  阅读(146)  评论(0)    收藏  举报