当前位置: 首页 > 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--;
            }
        }
    }
};

相关文章:

  • 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)
  • wordpress模板如何安装/泰州seo
  • 风格网站/广西网站建设制作
  • 电子商务综合实训报告网站建设/培训机构连锁加盟
  • 网站有域名没备案/互联网广告是做什么的
  • 今天的最新消息/合肥seo整站优化
  • 北京通州区网站制作/汕头seo优化