zoukankan      html  css  js  c++  java
  • LeetCode 283. Move Zeroes [two pointers]

    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:

    1. You must do this in-place without making a copy of the array.
    2. Minimize the total number of operations

    题目要求保持非零数字相对位置不变的前提下,把0移到末尾

    最开始的思路是遇见0之后,把所有的数字都向前移动一位,通过了大部分测试用例,但是无法处理连零的问题,代码如下:

     1 class Solution {
     2 public:
     3     void moveZeroes(vector<int>& nums) {
     4         int size = nums.size();
     5         for(int i=0;i<size;i++)
     6         {
     7             if(nums[i]==0)
     8             {
     9                 for(int j=i+1;j<size;j++)
    10                    nums[j-1]=nums[j];
    11                 nums[size-1]=0;
    12             }
    13         }
    14         
    15     }
    16 };

    换个思路,遍历两遍向量,记录下来0的数量,将非零数字存入新的向量,最后再将0补进新的向量,时间空间复杂度均是O(n),代码如下:

     1 void moveZeroes(vector<int>& nums) {
     2     int n = nums.size();
     3 
     4     // Count the zeroes
     5     int numZeroes = 0;
     6     for (int i = 0; i < n; i++) {
     7         numZeroes += (nums[i] == 0);
     8     }
     9 
    10     // Make all the non-zero elements retain their original order.
    11     vector<int> ans;
    12     for (int i = 0; i < n; i++) {
    13         if (nums[i] != 0) {
    14             ans.push_back(nums[i]);
    15         }
    16     }
    17 
    18     // Move all zeroes to the end
    19     while (numZeroes--) {
    20         ans.push_back(0);
    21     }
    22 
    23     // Combine the result
    24     for (int i = 0; i < n; i++) {
    25         nums[i] = ans[i];
    26     }
    27 }

    进一步优化,用两个指针,第一个指针记录最后一个非零元素应该在的位置,第二个指针负责遍历,遇见非零元素就把发赋值给第一个元素所在位置,然后第一个指针前进一个,第二次遍历则是把第一个指针到向量的末尾全部赋值为0。时间复杂度O(n),空间复杂度O(1);

     1 void moveZeroes(vector<int>& nums) {
     2     int lastNonZeroFoundAt = 0;
     3     // If the current element is not 0, then we need to
     4     // append it just in front of last non 0 element we found. 
     5     for (int i = 0; i < nums.size(); i++) {
     6         if (nums[i] != 0) {
     7             nums[lastNonZeroFoundAt++] = nums[i];
     8         }
     9     }
    10     // After we have finished processing new elements,
    11     // all the non-zero elements are already at beginning of array.
    12     // We just need to fill remaining array with 0's.
    13     for (int i = lastNonZeroFoundAt; i < nums.size(); i++) {
    14         nums[i] = 0;
    15     }
    16 }

    再优化操作方面,只遍历一遍,两个指针,思路同上,这次赋值变成交换位置,交换的次数为非零元素的个数

    1 void moveZeroes(vector<int>& nums) {
    2     for (int lastNonZeroFoundAt = 0, cur = 0; cur < nums.size(); cur++) {
    3         if (nums[cur] != 0) {
    4             swap(nums[lastNonZeroFoundAt++], nums[cur]);
    5         }
    6     }
    7 }
  • 相关阅读:
    selenium爬取沃尔玛分类和商品详情
    linux下部署redis
    linux系统基本操作命令
    Scrapy & Django项目
    爬虫爬取百度搜狗图片持久化存储
    django + vue 简单配置登录注册及分页和实例化
    vue安装及常用属性
    vue跨域配制
    Django中配置全文检索
    Django框架知识点简单总结(1)
  • 原文地址:https://www.cnblogs.com/dapeng-bupt/p/7887231.html
Copyright © 2011-2022 走看看