剑指Offer - 面试题21:调整数组顺序使奇数位于偶数前面

简介: 剑指Offer - 面试题21:调整数组顺序使奇数位于偶数前面

题目

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。


分析

暴力法

最简单能想到的就是从前到后依次遍历若发现是偶数,先保存当前元素,将后面全部往前移动,然后把保存的元素给到最后那个位置。时间复杂度为O(n2),空间复杂度为O(1);


C

#include<stdio.h>
#include<assert.h>
//暴力法
void ReordeOddEven(int* pData, unsigned int length)
{
    assert(NULL != pData);
    assert(length > 0);
    int i = 0;
    int j = 0;
    for(i = 0; i < length; i++)
    {
        if((pData[i] & 1) == 0)//&优先级低于==所以务必加括号,否则永远不成立
        {    
            int tmp = pData[i];
            for(j = i; j < length - 1; j++)
            {
                pData[j] = pData[j + 1];
            }
            pData[j] = tmp;
        }
    }
}
void Print(int* n, int length)
{
    int i = 0;
    for(i = 0; i < length; i++)
    {
        printf("%d ", n[i]);
    }
    printf("\n");
}
int main()
{
    int n[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int length = sizeof(n) / sizeof(n[0]);
    ReordeOddEven(n, length);
    Print(n, length);
    return 0;
}


双指针

我们还可以用俩个指针。分别指向头和尾巴。


让start指针向后走找偶数,让end指针向前走找奇数。循环条件:start<end

C

#include<stdio.h>
#include<assert.h>
void swap(int* n , int i, int j)
{
    int tmp = n[i];
    n[i] = n[j];
    n[j] = tmp;
}
void ReordeOddEven(int* pData, unsigned int length)
{
    assert(NULL != pData);
    assert(length > 0);
    int start = 0;
    int end = length - 1;
    while(start < end)
    {
        while(start < end && (pData[start] & 1) == 1)//如果是奇数就一直找
        {
            start++;
        }
        while(start < end && (pData[end] & 1) == 0)//如果是偶数就一直找
        {
            end--;
        }
        if(start < end)
        {
            swap(pData, start, end);
        }
    }
}
void Print(int* n, int length)
{
    int i = 0;
    for(i = 0; i < length; i++)
    {
        printf("%d ", n[i]);
    }
    printf("\n");
}
int main()
{
    int n[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int length = sizeof(n) / sizeof(n[0]);
    ReordeOddEven(n, length);
    Print(n, length);
    return 0;
}

具有扩展性的双指针


分析上面代码我们发现核心就只有俩段代码(pData[start] & 1)(pData[end] & 1),我们把这个代码封装成一个函数,这个地方直接调用封装好的函数就ok了。

C

#include<stdio.h>
#include<assert.h>
#include<stdbool.h>
bool func(int n)
{
    return (n & 1) == 0;
}
void swap(int* n, int i, int j)
{
    int tmp = n[i];
    n[i] = n[j];
    n[j] = tmp;
}
void ReordeOddEven(int* pData, unsigned int length)
{
    assert(NULL != pData);
    assert(length > 0);
    int start = 0;
    int end = length -1;
    while(start < end)
    {
        while(start < end && func(pData[start])  == false)
        {
            start++;
        }
        while(start < end && func(pData[end]) == true)
        {
            end--;
        }
        if(start < end)
        {
            swap(pData, start, end);
        }
    }
}
void Print(int* n, int length)
{
    int i = 0;
    for(i = 0; i < length; i++)
    {
        printf("%d ", n[i]);
    }
    printf("\n");
}
int main()
{
    int n[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
    int length = sizeof(n) / sizeof(n[0]);
    ReordeOddEven(n, length);
    Print(n, length);
    return 0;
}


本章完!

目录
相关文章
|
2月前
|
算法
【数组相关面试题】LeetCode试题
【数组相关面试题】LeetCode试题
|
2月前
|
存储
力扣面试经典题之数组/字符串
力扣面试经典题之数组/字符串
23 0
|
3月前
|
算法 前端开发
经典面试题:扁平化嵌套数组
经典面试题:扁平化嵌套数组
22 0
|
27天前
|
算法 C++ 索引
【力扣经典面试题】238. 除自身以外数组的乘积
【力扣经典面试题】238. 除自身以外数组的乘积
|
2月前
|
算法 测试技术 索引
力扣面试经典题之数组/字符串(二)
力扣面试经典题之数组/字符串(二)
13 0
|
3月前
|
JavaScript 前端开发 索引
【JavaScript】面试手撕数组原型链(易)
续借上文,这篇文章主要讲的是数组原型链相关的考题,有些人可能会纳闷,数组和原型链之间有什么关系呢?我们日常使用的数组forEach,map等都是建立在原型链之上的。举个🌰,如我有一个数组const arr = [1,2,3]我想要调用arr.sum方法对arr数组的值进行求和,该如何做呢?我们知道数组没有sum函数,于是我们需要在数组的原型上定义这个函数,才能方便我们调用,具体代码如下。接下来我们就是采用这种方式去实现一些数组常用的方法。
39 6
|
3月前
|
JavaScript 前端开发
【JavaScript】面试手写题精讲之数组(上)
该专题主要是讲解我们在面试的时候碰到一些JS的手写题, 确实这种手写题还是比较恶心的。有些时候好不容易把题目写出来了,突然面试官冷不丁来一句有没有更优的解法,直接让我们僵在原地。为了解决兄弟们的这些困扰,这个专题于是就诞生啦。我们会将一些常见的不是最优解的答案作为对比,方便大家更好理解。
38 3
|
4月前
|
存储 算法 Java
数据结构和算法面试题:给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
数据结构和算法面试题:给定一个整数数组 nums,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
43 0
|
4月前
|
算法 Java C++
数据结构与算法面试题:实现一个函数 fill(int[] a, int n, int v),使其将大小为 n 的数组 a 填满为 v。
数据结构与算法面试题:实现一个函数 fill(int[] a, int n, int v),使其将大小为 n 的数组 a 填满为 v。
16 0
|
4月前
|
存储 C++
面试题:数组和指针的区别?
面试题:数组和指针的区别?
26 0