题目来源:剑指offer

题目:

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

解题思路:

数组类题目指导原则:除了极其傻瓜式的题目,大部分数组类的题目都要用到 “双索引“策略,只不过有的采用对撞指针,有的采用跟随指针。

我们随便举出一个数组的例子,才分析怎么做才比较合适:2 4 7 4 3 5 8  10 9;

那么此时,你会怎么做,当然了,我们当然是需要找出所有的奇数,以及所有的偶数。基于这种找的思想,我们当然可以这么做:从头到尾判定这个数组的每个元素的奇偶性,然后生成一个和该数组同样大小的数组空间,将扫描到的奇数按原顺序放在新数组的前半部分,再将是扫描到的偶数放到新数组的后半部分,毫无疑问,这种策略但从结果上看,是没有任何问题的,问题在于:我们使用了一个和原数组同样大小的数组空间。这使得时间复杂度和空间复杂度都为O(n)可见,这样并不是一个好方法。有没有更好的方法呢?

当然有:

请别忘记我们最终要做的是:将奇数按照原来的顺序放到前面,偶数按照原来的顺序放到后面。有没有可能,我们仅仅在原空间上,做数据搬移就能实现这个愿望呢?答案是有的。

那么我们要发出的一个很自然的问题是:什么时候我们进行这种搬移?

当然是某一个奇数和它前面(左边)离他最远偶数之间,存在这种搬移。那么此时,很明显的需要两个索引来标识两个奇数和偶数。比如 上述序列:2 4 7 ,我们当然知道,正确的顺序是 7 2 4。那么我们应该怎么做呢?

代码:

我给出下面的核心代码,你大概就可以看懂了:

             tmp = array[j];//将奇数缓存起来
for(int k = j;k>i;k--)
array[k] = array[k-];
array[i] = tmp;//将奇数放到它应该在的位置

很明显,我们的做法是:将 7 缓存到一个变量中去,然后,将所有的偶数向后搬移一个单位,再将7放到它应该在的位置。上述代码就是解决这个问题的核心思路。

但我在调试的过程中仍然遇到了数组越界这样的问题:

我先把我的完整代码放在下面,以供参考:

 class Solution {
public:
void reOrderArray(vector<int> &array) {//tow pointer
int length = array.size();
int i = ;//奇数索引位置
int j = ;
int tmp;
if(length > )
{
while((i < length) &&(j < length))
{
while((i< length) && (array[i]% == ))
{//找到第一个偶数
i++;
}
j = i+;
while((j< length) && (array[j]% == ))
{//找到第一个奇数
j++;
}
if((j == length) || (i == length))
break;
tmp = array[j];//将奇数缓存起来
for(int k = j;k>i;k--)
array[k] = array[k-];
array[i] = tmp;//将奇数放到它应该在的位置
}
}
}
};

上述代码中,i和j就表示了双索引。在上述代码中,我多次将 i和j索引值与数组长度length作比较,目的就是为了防止越界。

比如:开头的if(length > 1),则是为了说明这个数组至少有两个元素。下述的找到第一个奇数和第一个偶数,我们也加上 i < length和 j < length的限制。目的是为了避免越界,比如:加入数组为全奇数和或者全偶数的情况,必然会导致越界。

总结:

我在思考核心代码上画的时间并不是很多,但是在防止数组越界的问题折腾了很久,最终才提交上去,我想表明的观点是:

  • 凡是数组问题必然要考虑越界问题,及时进行边界约束。
  • 凡是数组问题,我们一定要考虑数组为空,数组中有一个元素,数组中有n个元素的情况
  • 凡是数组问题,双索引几乎成了一个必选的 解决思路。

请记好上述三个凡是!!!

牛客网剑指offer第13题——调整数组顺序使得奇数位于偶数前面的更多相关文章

  1. 剑指offer(13)调整数组顺序使奇数位于偶数前面

    题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 题目分析 判断是 ...

  2. 【剑指Offer】13、调整数组顺序使奇数位于偶数前面

      题目描述:   输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变.   解题思 ...

  3. 剑指Offer - 九度1516 - 调整数组顺序使奇数位于偶数前面

    剑指Offer - 九度1516 - 调整数组顺序使奇数位于偶数前面2013-11-30 02:17 题目描述: 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部 ...

  4. 剑指Offer:面试题14——调整数组顺序使奇数位于偶数前面(java实现)

    问题描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分. 思路: 1.最简单的想法,不考虑时间复杂度,扫描数组,遇到偶数,先取出这 ...

  5. C++版 - 剑指offer面试题14: 调整数组顺序使奇数位于偶数前面

    题目: 调整数组顺序使奇数位于偶数前面 热度指数:11843 时间限制:1秒 空间限制:32768K 本题知识点: 数组 题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇 ...

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

    def isOdd(n): return n & 1 def Reorder(data, cf = isOdd): odd = 0 even = len( data ) - 1 while T ...

  7. 【Offer】[21] 【调整数组顺序使奇数位于偶数前面】

    题目描述 思路分析 测试用例 Java代码 代码链接 题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,(偶数之间和奇数 ...

  8. 牛客网剑指offer第19题——顺时针打印矩阵

    这个题看似很简单: 题目: 输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字,例如,如果输入如下4 X 4矩阵: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 1 ...

  9. 牛客网剑指offer第21题——判断出栈序列是否是入栈序列

    题目: 输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序.假设压入栈的所有数字均不相等.例如序列1,2,3,4,5是某栈的压入顺序,序列4,5,3,2,1是该压栈 ...

随机推荐

  1. Java:线程的六种状态及转化

    目录 Java:线程的六种状态及转化 一.新建状态(NEW) 二.运行状态(RUNNABLE) 就绪状态(READY) 运行状态(RUNNING) 三.阻塞状态(BLOCKED) 四.等待状态(WAI ...

  2. python学习Day06--编码

    [主要内容] 1. is 和 == 区别 id()函数 == 判断两边的值 is 判断内存地址回顾编码: 1. ASCII: 英文, 特殊字符, 数字, 8bit, 1byte 2. GBK: 中文 ...

  3. C++ 强制类型转换详解

    类型转换只不过是让编译器以另外一种方式解释一块内存而已.C++兼容C语言的强制类型转换方式,同时也提供了新型的基于模板的类型转换方式,来提供更多的安全性. 一.C风格的强制类型转换 double k ...

  4. Hibernate(六)

    ================================缓存============================定义:介于应用程序和永久性数据存储源之间,可以复制数据存储源中的数据. 工作 ...

  5. Java.work7 访问权限、对象使用作业20194651

    题目1: 在作业5的基础上,再创建一个柱体类,包含矩形对象.高和体积等三个成员变量,一个构造方法进行成员变量初始化,和计算体积.换底两个功能方法,在主类中输入长.宽.高,计算柱体体积,输入新的长.宽. ...

  6. 【笔记】最短路——SPFA算法

    ##算法功能 找最短路(最长路?) ##算法思想 用一个节点k更新节点i到节点j的最短路 ##邻接链表存储 基础而高效的图的存储方式 存的是单向边(无向边可以看成两条有向边) ##实现 维护节点i到源 ...

  7. cmake处理多源文件目录的方法(转)

    cmake处理源代码分布在不同目录中的情况也很简单,现在假设我们的源代码分布情况如下: 源代码的分布情况 其中src目录下的文件要编译成一个链接库 第一步,项目主目录中的CMakelist.txt 在 ...

  8. Python3(四) 分支、循环、条件与枚举

    表达式        表达式(Expression)是运算符(operator)和操作数(operand)所构成的序列 >>> 1 + 1 2 >>> a = [1 ...

  9. Hexo搭建静态博客踩坑日记(一)

    前言 博客折腾一次就好, 找一个适合自己的博客平台, 专注于内容进行提升. 方式一: 自己买服务器, 域名, 写前端, 后端(前后分离最折腾, 不分离还好一点)... 方式二: 利用Hexo, Hug ...

  10. tomcat 多端口 多容器 多域名 配置

    先强调一个原则: server下面可以有多个service,用于配置不同监听端口 service下面可以有多个Host,用于配置该端口下的不同域名 Host里可以包含多个Context,用于配置该端口 ...