【剑指offer】调整数组顺序使奇数位于偶数前面

news2024/11/26 17:38:10

文章目录

  • 题目
  • 思路
  • 相对位置可以改变的思路
  • 相对位置不能改变的思路


题目

题目链接入口:调整数组顺序使奇数位于偶数前面
在这里插入图片描述

示例1:
输入:[1,2,3,4,5,6]
结果:[1,3,5,2,4,6]

示例2:
输入:[1,2,2,3,4,4,5,6,7]
结果:[1,3,5,7,2,2,4,4,6]

思路

1.核心考点:数组操作,排序(插入排序)思想的扩展使用
2.原题变形:这道题目加了一个条件:要求相对位置不变。这里先讲讲相对位置可以改变的情况,这样能更好的理解“什么叫相对位置不变”。

相对位置可以改变的思路

(1)使用双(头尾)指针法,一个指向数组的第一个元素,一个指向数组的最后一个元素。
在这里插入图片描述

(2)当begin指向的元素是偶数,begin停下,当end指向的元素是奇数,end也停下,然后交换begin和end指向的元素。

在这里插入图片描述
(3)注意临界条件:我们不仅要在最外层循环添加条件begin<end,在begin++,end–的过程中,我们也要保持begin<end

大家可以发现,[1,2,3,4,5,6]若相对位置可以发生改变,得到的结果是[1,5,3,4,2,6],原来3本来在5的前面,结果5在交换过后,跑到3前面去了,那么这就是相对位置发生改变。
若要求相对位置不变,结果是[1,3,5,2,4,6](示例中),结果3依然是在5前面的,保持了相对位置不发生改变。

这种方法的代码如下:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
class Solution {
public:
	void reOrderArray(vector<int> &array) {
		if (array.size() == 0)
		{
			return;
		}
		int begin = 0;
		int end = array[array.size() - 2];

		while (begin < end)
		{
			while (begin < end&&array[begin] & 1)//是奇数则++,遇到偶数才停下
			{
				begin++;
			}
			while (begin < end && (!(array[end] & 1)))//是偶数则--,遇到奇数才停下
			{
				end--;
			}
		    //交换
			if(begin < end)
			{
				swap(array[begin], array[end]);
			}
		}
	}
};
int main()
{
	Solution s;
	vector<int> array{ 1,2,3,4,5,6};
	s.reOrderArray(array);

	return 0;
}

相对位置不能改变的思路

(1)这道题的关键点在于:奇数要位于偶数前面,并且!奇数偶数的相对位置相较于原数组的顺序不能发生改变。
(2)采用插入排序的思想:找到奇数依次插入到前面,偶数整体后移。

定义i=0,用于遍历原数组(找到奇数),然后用tmp临时变量保留奇数tmp=array[i],遍历找到的第一个奇数肯定放在下标为0的位置,第二个奇数肯定放在下标为1的位置,所以我们还要定义一个变量k,去记录已经插入的奇数的位置array[k++]=tmp(用于将奇数前插置k下标位置处,这种做法就保证了奇数的相对位置不会改变)。那么偶数如何做到整体后移,不改变相对位置的顺序呢?

由于i用来遍历数组,所以i不能被改变,我们用变量j进行操作,使j=i,这个时候array[j]是我们找到的奇数,现在前面的偶数整体向后移动,即array[j]=array[j-1],也就是说我们当前找到的奇数就被覆盖了(这个操作也保证了偶数的相对位置不发生改变),这也正是我们为什么要用临时变量tmp保存奇数的原因。

解释代码的两个点
1.我们用array[i]&1来判断是否是奇数,原因在于二进制序列的第一位是2的0次方就是1,其它位置都是偶数,所以若第一位是1,那么这个数必是奇数。

2.偶数后移的循环条件j>k:由于k记录奇数已经插入的奇数的位置,所以j必须>k,保证前面已经调整好的奇数不被影响。

建议大家通过编译器调试窗口对各个变量进行解读,通过监视窗口,以及各个变量的变化,更能看出奇数前插,偶数整体后移的过程。我在这里大概写一下。

在这里插入图片描述

代码如下:

C++版本:

class Solution {
public:
    void reOrderArray(vector<int> &array) {
        if(array.size()==0)
        {
            return;
        }
        int k=0;//用于前插奇数
        int j=0;
        for(int i=0;i<array.size();i++)//
        {
            if(array[i]&1)//奇数的二进制最后一位是1
            {
                j=i;//i不能被改变,所以用j
                int tmp=array[i];//保留奇数,前插置k下标位置处
                while(j>k)//必须保证j>k,否则就会破坏已经排好的奇数序列
                {
                    array[j]=array[j-1];//偶数整体后移
                    j--;
                }
                array[k++]=tmp;
            }
        }
    }
};

java版本:

public class Solution {
    public void reOrderArray(int [] array) {
        int k = 0;
        for (int i = 0; i < array.length; i++) {
            if ((array[i] & 1) ==1) { //从左向右,每次遇到的,都是最前面的奇数,一定将来要被放在k下标处
                int temp = array[i];//现将当前奇数保存起来
                int j = i;
                while (j > k) { //将该奇数之前的内容(偶数序列),整体后移一个位置
                    array[j] = array[j - 1];
                    j--;
                }
                array[k++] =temp;//将奇数保存在它将来该在的位置,因为我们是从左往右放的,没有跨越奇数,所以一定是相对位置不变的
                 }
            }
        }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627391.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2023年前端面试高频考点之 通信(渲染、http、缓存、异步、跨域)

目录 浏览器从输入url到渲染页面 过程⭐⭐⭐ Http和Https区别⭐⭐⭐ GET和POST发送请求⭐⭐⭐ 异同 http版本⭐⭐⭐ http状态码⭐⭐⭐ TCP⭐⭐⭐ 三次握手 四次挥手 流量控制&#xff08;滑动窗口机制&#xff09; 拥塞控制 keep-alive持久连接 TCP⭐⭐⭐ 三次握手…

Revit中绘制多坡度的迹线屋顶和构件对齐

一、Revit中创建特殊多坡度的迹线屋顶 在我们的日常生活中可以见到一些建筑屋顶为偏欧式风格的屋顶&#xff0c;而有时候在做迹线屋顶时也需要作出如图一所示的效果&#xff0c;说明特殊的多坡度屋顶也是应用非常广泛的&#xff0c;那我们应该如何实现绘制呢? 1.要得到如上图所…

Linux系统:安装及管理程序

安装及管理程序 一、linux源码包&#xff1a;1.源码包&#xff1a;2.二进制包&#xff1a;3.源码包的好处&#xff1a;4.源码包不足&#xff1a; 二、编译安装的过程&#xff1a;1.重点步骤&#xff1a; 三、挂载1.格式&#xff1a;2.挂载规则&#xff1a; 四、应用程序和系统命…

使用Jmeter进行性能测试的这套步骤,涨薪2次,升职一次

项目背景&#xff1a; 我们的平台为全国某行业监控平台&#xff0c;经过3轮功能测试、接口测试后&#xff0c;98%的问题已经关闭&#xff0c;决定对省平台向全国平台上传数据的接口进行性能测试。 01、测试步骤 1、编写性能测试方案 由于我是刚进入此项目组不久&#xff0c…

2023年专业连锁行业研究报告

第一章 行业概况 专业连锁行业是指以连锁经营模式运营的公司&#xff0c;其主要业务涵盖零售、餐饮、酒店、医疗、教育等领域。这些公司通过规模化、标准化的经营模式和供应链管理&#xff0c;提供专业化、高质量的产品和服务。专业连锁行业在全球范围内蓬勃发展&#xff0c;并…

LeetCode - 1 两数之和

目录 题目来源 题目描述 示例 提示 题目解析 算法源码 题目来源 1. 两数之和 - 力扣&#xff08;LeetCode&#xff09; 题目描述 给定一个整数数组 nums 和一个整数目标值 target&#xff0c;请你在该数组中找出和为目标值 target 的那 两个整数&#xff0c;并返回它们…

Jmeter接口测试实战篇:10分钟学会Jmeter的用法

一提到接口测试&#xff0c;通常大家会有这样的疑问&#xff1a;前端测试不是已经覆盖到各种业务逻辑了吗&#xff1f;为什么还要做接口测试&#xff0c;接口测试和前端测试是不是重复了&#xff1f;对于这个问题&#xff0c;可以从下面几个方面来解释&#xff1a; 什么是接口…

架构之冷热分离

本文依据《从程序员到架构师》阅读有感&#xff0c;记录书中案例并且结合作者工作经历进行分析。 当数据量过大&#xff0c;业务查询慢甚至导致数据库服务器CPU飙升&#xff0c;导致数据库宕机&#xff0c;影响用户体验。 场景&#xff1a; 1.客户两年多产生了近2000万的工单…

k聚类简单实现(灰度分割,分黑白)

加载图像&#xff1a; k聚类分割后图像&#xff0c;分成黑白两类&#xff0c;故意把结果黑色类染红&#xff0c;核对发现是正确的&#xff1a; 具体算法如下&#xff1a; float globu1 40; float globu2 180; public void k均值迭代法更新(int imgw, int imgh, byte…

云晶-新一代云上操作系统的新定义,价值,应用范围

本文&#xff0c;从人类社会信息化到数字化的演变过程&#xff0c;以及当前的企业数字化现状&#xff0c;并回顾信息技术的几次革命来阐述总结操作系统的价值和意义。我们基于行业发展规律&#xff0c;重新定义了云晶-云上操作系统的架构和建设要点。并给出了大胆设想。 您也许…

大模型部署实战(一)——Ziya-LLaMA-13B

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

【TA100 】图形 2.1 色彩空间介绍

->如何描述色彩 不要感性的认知&#xff0c;我们来 正经讨论&#xff0c;探究问题的本质- - ->色彩科学。 一、色彩发送器&#xff08;光源发射角度&#xff09; ->以面向对象的思想来理解&#xff1a; ● 出生点&#xff1a;光源 ● Object&#xff1a;射线&#…

15 【Vue-Router】

1.相关理解 1.1 vue-router 的理解 vue的一个插件库&#xff0c;专门用来实现SPA应用 1.2 对SPA应用的理解 1.单页Web应用&#xff08;single page web application&#xff0c;SPA&#xff09; 2.整个应用只有一个完整的页面 3.点击页面中的导航链接不会刷新页面&#xff…

STM32任务调度

目录 什么是任务调度&#xff1f; FreeRTOS的任务调度规则是怎样的&#xff1f; 抢占式调度运行过程 时间片调度运行过程 任务的状态 任务综合小实验 实验需求 cubeMX配置 什么是任务调度&#xff1f; 调度器就是使用相关的调度算法来决定当前需要执行的哪个任务。 Fr…

编程新手如何提高编程能力?

如果刚开始写代码时能读一读《整洁代码的艺术》那是个不错的选择。这本书会告诉您&#xff0c; 如何应用九大原则来提高编程能力。 良好的编程技能带来更整洁的代码&#xff0c; 让您更专注、更有效地利用时间&#xff0c;得到更高质量的结果。只要应用本书中提到的那些原则&am…

springboot集成rabbitmq

简介 RabbitMQ 是实现 AMQP&#xff08;高级消息队列协议&#xff09;的消息中间件的一种&#xff0c;最初起源于金融系统&#xff0c;用于在分布式系统中存储转发消息&#xff0c;在易用性、扩展性、高可用性等方面表现不俗。 RabbitMQ 主要是为了实现系统之间的双向解耦而实…

【LeetCode】HOT 100(4)

题单介绍&#xff1a; 精选 100 道力扣&#xff08;LeetCode&#xff09;上最热门的题目&#xff0c;适合初识算法与数据结构的新手和想要在短时间内高效提升的人&#xff0c;熟练掌握这 100 道题&#xff0c;你就已经具备了在代码世界通行的基本能力。 目录 题单介绍&#…

容器(第三篇)docker-cgroup资源限制

Docker 通过 Cgroup 来控制容器使用的资源配额&#xff0c;包括 CPU、内存、磁盘三大方面&#xff0c; 基本覆盖了常见的资源配额和使用量控制。 Cgroup 是 ControlGroups 的缩写&#xff0c;是 Linux 内核提供的一种可以限制、记录、隔离进程组所使用的物理资源(如 CPU、内存、…

一路狂飙,性能测试流程与性能测试主要指标整理,直接上高速...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 性能测试实战 性…

什么是真正的需求,如何才能找到?

此为内容创作模板&#xff0c;在发布之前请将不必要的内容删除 对需求本身的误判&#xff0c;比错误本身更为恐怖&#xff0c;直接导致必然失败的局面。 工作失误必不可免&#xff0c;好工作核心在于有需求&#xff0c;自己需要去做&#xff0c;有动力&#xff0c;别人需要你…