当前位置: 首页 > news >正文

数组分块问题 【刷题反思】

1. 数组分两块

1.1 题目

题目描述:给一个数组 nums ,写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序

请注意,必须在不复制数组的情况下原地对数组进行操作

示例:

        输入:

             nums = [0,1,0,3,12]

        输出:

             nums = [1,3,12,0,0]

class Solution
{
 public:
    void moveZeroes(vector<int>& nums)
 {
        
 }
};

1.2 思想

无非是将数组分为三部分,第一部分为非0元素,第二部分为全0元素,第三部分为待扫描元素

我们可以定义一个下标 cur 来作为分界线,定义 i 来遍历数组,[ 0,cur ]为非0元素,[ cur+1,i ]为0元素,[ i,n-1 ]为待扫描元素

1.3 模拟实现

#include<vector>
class Solution
{
public:
    void moveZeroes(vector<int>& nums)
    {
        //定义cur表示非0和0两块的分界线,i来遍历数组
        //因为,cur标记[ 0,cur ],所以cur初始为0
        int cur = -1, i = 0;
        while (i != nums.size())
        {
            //如果nums[i]==0,直接i++,将这个数纳入[cur+1,i]这个范围
            if (nums[i] == 0) i++;
            //如果nums[i]!=0,已知[0,cur],[cur+1,i],[i,n-1]这3个范围,将nums[cur+1]和nums[i]交 
            //换,再将cur++,把这个数纳入[0,cur]的范围
            else
            {
                swap(nums[cur + 1], nums[i]);
                cur++;
                i++;
            }
        }
    }
};

2. 数组分三块

2.1 题目

题目描述:给一个包含红色、白色和蓝色、共 n 个元素的数组 nums1,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列

我们使用整数0、1和2分别表示红色、白色和蓝色

必须在不使用库内置的 sort 函数的情况下解决这个问题

示例:

输入: nums = [ 2,0,2,1,1,0 ]

输出:   nums = [ 0,0,1,1,2,2 ]

class Solution {
public:
    void sortColors(vector<int>& nums) {
        
    }
};

2.2 思想

和荷兰国旗问题一样,这类问题就是将数组分为三块,我们可以再填加一个指针(数组下标)

这里数组大小设为 n,定义三个指针:left,i,right

[ 0,left ] 为0,[ left+1,i-1 ]为1,[ i,right-1]为未扫描,[ right,n-1 ]为2

2.3 模拟实现

#include<vector>
class Solution {
  public:
    void sortColors(vector<int>& nums) {
        //[0,left],要包含0,left初始化为-1
        //[right,n-1],要包含下标n-1,right初始化为数组大小
        int left = -1, i = 0, right = nums.size();
       while (i < right)
        {
           //[0,left],[left+1,i-1],[i,right-1],[right,n-1]
           //nums[i]和nums[left+1]交换,left++就可以将0放入[0,left]中
           if (nums[i] == 0)
            {
               swap(nums[i], nums[left + 1]);
                left++;
                i++;
            }
           
            else if (nums[i] == 1)
            {
               i++;
            }
            //nums[i]和nums[right-1]交换,right--,将2放入[right,n-1]中
            //注意:nums[right-1]还没有判断,交换后也没有判断,所以i不能++
            else 
            {
                swap(nums[i], nums[right - 1]);
                right--;
            }
        }
    }
};

http://www.dtcms.com/a/33564.html

相关文章:

  • doris:使用 Hint 调整 Join Shuffle 方式
  • Java 阻塞队列:让并发更“懂事”
  • Matplotlib,Streamlit,Django大致介绍
  • Day26 第七章 回溯算法part05
  • 基于PSO粒子群优化的BiLSTM双向长短期记忆网络序列预测算法matlab仿真,对比BiLSTM和LSTM
  • mysql大数量表添加索引方案
  • Linux提权之环境劫持提权(九)
  • 大语言模型中的 Token如何理解?
  • Linux 命令大全完整版(03)
  • 【嵌入式Linux应用开发基础】多线程编程
  • 基于AIGC的图表自动化生成工具「图表狐」深度评测:如何用自然语言30秒搞定专业级数据可视化?
  • ABC381E题解
  • 数据结构之二叉树的定义及实现
  • Unity使用IL2CPP打包时,我们应该注意什么?如何避免(可以举例说明)
  • 创建虚拟环境以及配置对应的项目依赖
  • DeepSeek技术全景解析:架构创新与行业差异化竞争力
  • Spring Boot数据访问(JDBC)全解析:从基础配置到高级调优
  • 20-R 绘图 - 饼图
  • 游戏设计模式阅读 - 游戏循环
  • Spring Security+JWT (5)
  • 红队内网攻防渗透:内网渗透之内网对抗:实战项目VPC2打靶父子域三层路由某绒免杀下载突破约束委派域控提权
  • 深度解析:大模型在多显卡服务器下的通信机制与分布式训练——以DeepSeek、Ollama和vLLM为例
  • 安全面试4
  • 谷歌浏览器更新后导致的刷新数据无法显示
  • C++标准库提供了哪些智能指针类型以及它们的区别
  • 小红书运营教程(内容笔记01)
  • 网络安全 | 信息安全管理体系(ISMS)
  • Linux文件系统----磁盘级文件
  • 《GNU/Linux Shell命令全解析》
  • CSS背景属性