首页 > 其他分享 >刷题 | 数组移动元素

刷题 | 数组移动元素

时间:2023-05-03 20:45:01浏览次数:36  
标签:遍历 nums ++ 元素 int 数组 刷题

题目描述

LeetCode.283. 移动零

给定一个数组 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


解法1

算法思想:

  1. 创建一个数组tmps用于存储nums中所有的非零元素(按原有顺序存储),遍历nums,将非零元素存于tmps中。
  2. 遍历tmps,将tmps中元素覆盖nums元素(从0号下标开始依次覆盖)。
  3. 将nums剩余位置元素置零。

时间复杂度=O(n)

空间复杂度=O(n)

代码实现:

#include <iostream>
#include <vector>

using namespace std;

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        vector<int> tmps;
        int i;
        for(i = 0; i < nums.size(); i++){
            if(nums[i] != 0){
                tmps.push_back(nums[i]);
            }
        }
        for(i = 0; i < tmps.size(); i++){
            nums[i] = tmps[i];
        }
        for(; i < nums.size(); i++){
            nums[i] = 0;
        }
    }
};

int main()
{
   int arr[] = {0, 1, 0, 3, 12};
   vector<int> vec(arr, arr + sizeof(arr) / sizeof(int));
   Solution().moveZeroes(vec);
   for(int i = 0; i < vec.size(); i++){
    cout << vec[i] << " ";
   }
   cout << endl;
   system("pause");
   return 0;
}

运行效果:

1 3 12 0 0

解法2

算法思想:

原地操作,不开辟新的内存空间

  1. 声明两个指针i和k,i:用于遍历数组,k:保证[0...k)中保存所有当前已遍历过的所有非0元素;

    即:遍历完第i个元素后,[0...i]中所有非0元素都按照原有顺序排列再[0...k)中。

  2. 若当前元素nums[i]为0元素,忽略,继续向前遍历;

  3. 若当前元素nums[i]为非0元素,将该元素插入到nums[k]的位置,然后i++,k++;

  4. 重复上述操作,直至指针i遍历结束;

  5. 从位置k开始遍历数组,将元素值置零。

代码实现:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int i, k = 0;
        for(i = 0; i < nums.size(); i++){
            if(nums[i] == 0){
                continue;
            }else{
                nums[k++] = nums[i];
            }
        }
        for(i = k; i < nums.size(); i++){
            nums[i] = 0;
        }
    }
};

相当于把数组nums分成左右两部分:

  • 左部分:已处理元素集合,存储数组中已经处理完毕的非零元素(处理完毕即元素均为非0元素且按原有顺序排列),左右边界为[0...k),初始时k=0代表左部分为空;
  • 右部分:待处理元素集合,左右边界为[k...nums.size()-1],初始时k=0代表整个数组。

解法3:

算法思想:

在解法2的基础上进一步优化,去掉解法2最后一步将数组剩余元素置零的操作。

  1. 声明两个指针i和k,i:用于遍历数组,k:保证[0...k)中保存所有当前已遍历过的所有非0元素;

    即:遍历完第i个元素后,[0...i]中所有非0元素都按照原有顺序排列再[0...k)中。

  2. 若当前元素nums[i]为0元素,忽略,继续向前遍历;

  3. 若当前元素nums[i]为非0元素,将该元素与nums[k]对应元素交换位置,然后i++,k++;

  4. 重复上述操作,直至指针i遍历结束;

代码实现:

class Solution {
public:
    void swap(int &a, int &b){
        int tmp = a;
        a = b;
        b = tmp;
    }
    void moveZeroes(vector<int>& nums) {
        int i, k = 0;
        for(i = k; i < nums.size(); i++){
            if(nums[i] == 0){
                continue;
            }else{
                swap(nums[k++], nums[i]);
            }
        }
    }
};

进一步优化:

若数组nums全是非零元素,按照上述代码,每个元素(均为非0元素)都会和自己执行一次交换,耗时。

class Solution {
public:
    void swap(int &a, int &b){
        int tmp = a;
        a = b;
        b = tmp;
    }
    void moveZeroes(vector<int>& nums) {
        int i, k = 0;
        for(i = k; i < nums.size(); i++){
            if(nums[i] == 0){
                continue;
            }else{
                if(nums[k] == 0){
                    swap(nums[k++], nums[i]);
                }else{
                    k++;
                }
            }
        }
    }
};

相似题目

leetcode.27. 移除元素

class Solution {
public:
    int removeElement(vector<int>& nums, int val) {
        int k = 0;
        for(int i = k; i < nums.size(); i++){
            if(nums[i] != val){
                nums[k++] = nums[i];
            }
        }
        return k;
    }
};

leetcode.26. 删除有序数组中的重复项

/*
算法思想:
    声明指针k,将数组划分成两部分:nums[0...k)为已处理序列,nums[k...]为待处理序列,k初始时为0
    声明指针i遍历数组:
        1. 若已处理序列为空(即k==0),则将当前元素nums[i]插入到k位置,并执行k++;
        2. 若已处理序列非空,将当前元素nums[i]与已处理序列尾元素nums[k-1]比较:
            (1)若二者相等,忽略当前元素,继续遍历;
            (2)若二者不等,将当前元素nums[i]插入到k位置,并执行k++。
*/
class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int k = 0;
        for(int i = 0; i < nums.size(); i++){
            if(k == 0){
                nums[k++] = nums[i];
            }else{
                if(nums[i] != nums[k-1]){
                    nums[k++] = nums[i];
                }
            }
        }
        return k;
    }
};

leetcode.80. 删除有序数组中的重复项 II

将leetcode.26中的nums[i] != nums[k-1]改为nums[i] != nums[k-2]即可。

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        int k = 0;
        for(int i = 0; i < nums.size(); i++){
            if(k == 0){
                nums[k++] = nums[i];
            }else{
                if(nums[i] != nums[k-2]){
                    nums[k++] = nums[i];
                }
            }
        }
        return k;
    }
};

标签:遍历,nums,++,元素,int,数组,刷题
From: https://www.cnblogs.com/lijiuliang/p/17369649.html

相关文章

  • vue学习 第九天(1) 元素的显示与隐藏 display (不保留位置) / visibility (保留位置) /
    元素的显示与隐藏本质:让一个元素在页面中隐藏或者显示出来。1、display属性,隐藏后不保留位置1)display::none;隐藏对象2)display:block;除了转换为块级元素之外,同时还有显示元素的意思。display隐藏元素后,不再占有原来的位置。 2......
  • smarty section循环显示一维数组元素
    <?phpheader("Content-type:text/html;charset=utf-8");//设置中国时区date_default_timezone_set('PRC');require_once("./Smarty/libs/Smarty.class.php");$smarty=newSmarty();$smarty->left_delimiter="<{";$sm......
  • JAVA中的数组详解
    JAVA中的数组二维数组的静态初始化格式:数据类型[][]数组名=new数据类型[][]{{},{},{}};简化:数据类型[][]数组名={{元素1,元素2},{元素1,元素2},{元素1,元素2}};int[][]arr={{11,22},{11,22}}; 动态初始化格式:数据类型[][]数组名=new数据类型[m]......
  • 第139篇:JS数组常用方法(map(),reduce(),foreach())
    好家伙,本篇为MDN文档数组方法的学习笔记Array.prototype.reduce()-JavaScript|MDN(mozilla.org)数组方法这块的知识缺了,补一下 1.map()方法map() 方法创建一个新数组,这个新数组由原数组中的每个元素都调用一次提供的函数后的返回值组成。constarray1=[1,4,9,......
  • smarty 显示二维数组
    <?phpheader("Content-type:text/html;charset=utf-8");//设置中国时区date_default_timezone_set('PRC');require_once("./Smarty/libs/Smarty.class.php");$smarty=newSmarty();$smarty->left_delimiter="<{";$sm......
  • c# 流、文件、字符串与byte数组、字符编码
    c#中的流对象间进行信息或者数据的交换时总是先将对象或数据转换为某种形式的流,再通过流的传输,到达目的对象后再将流转换为对象数据。所以,可以把流看作是一种数据的载体,通过它可以实现数据交换和传输。流的特殊性在于它是动态的和线性的,动态是指数据的内容和时间有关,例如,在某......
  • 81.数组
    1.一维数组的基本概念  数组是一组数据类型相同的变量,可以存放一组数据。1)创建数组  声明数组的语法:数据类型数组名[数组长度];  注意:数组长度必须是整数,可以是常量,也可以是变量和表达式。  C90规定必须用常量表达式指明数组的大小,C99允许使用整型非常量表达式。经......
  • 初识数组
    数组:一组相同类型的元素的集合 arr是数组名字,在数组里面存放10个数,如大括号里的没有设定的数多时,剩下的数都默认为0数组使用下标来访问的在数组开辟了一个空间,里面存放了这10个元素,这个数组的名字叫arr,而每个元素都有一个下标,但语法规定第一个元素下标都是为0,当你想访问每个......
  • nacos1.4读取properties配置文件中的数组对象,实现动态更新
     方法一:不可自动更新配置,有待检查。packagecom.javaweb.admin.config;importcom.alibaba.nacos.api.config.ConfigType;importcom.alibaba.nacos.api.config.annotation.NacosConfigurationProperties;importlombok.Data;importorg.springframework.context.annotat......
  • ABCEX 刷题记录
    ABC212HNimCounting先手获胜只需要异或和不为\(0\)。用生成函数解决。对多项式FWT把点值求出来,对多项式等比数列求和就相当于对点值等比数列求和。ABC213HStroll第一反应想了个假做法,对边权\(dft\)出点值,然后对\(T\)个点值做。但是这是一张无向图,而不是\(dag\),......