剑指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;
}


本章完!

目录
相关文章
|
4月前
|
C语言
【Amazon 面试题1】一个数组,里面得数出现的次数是偶数次,只有一个数出现的次数是奇数次,找出那个出现奇数次的数
本文介绍了解决Amazon面试题的一种方法,即在一个所有数字出现次数都是偶数,除了一个数字出现奇数次的数组中,利用异或运算的性质找出出现奇数次的数字,并提供了C语言实现的代码示例。
70 1
|
4月前
|
Java
Java 基础语法-面试题(54-63道)(数组+类+包)
Java 基础语法-面试题(54-63道)(数组+类+包)
46 16
|
4月前
|
安全 编译器 C++
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
【剑指offer】2.2编程语言(p22-p25)——面试题1:string赋值运算函数
|
5月前
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
|
6月前
|
开发框架 .NET
技术好文共享:面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
技术好文共享:面试题:找出数组中只出现一次的2个数(异或的巧妙应用)(出现3次)
|
4月前
|
存储 Java
【IO面试题 四】、介绍一下Java的序列化与反序列化
Java的序列化与反序列化允许对象通过实现Serializable接口转换成字节序列并存储或传输,之后可以通过ObjectInputStream和ObjectOutputStream的方法将这些字节序列恢复成对象。
|
28天前
|
存储 缓存 算法
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
本文介绍了多线程环境下的几个关键概念,包括时间片、超线程、上下文切换及其影响因素,以及线程调度的两种方式——抢占式调度和协同式调度。文章还讨论了减少上下文切换次数以提高多线程程序效率的方法,如无锁并发编程、使用CAS算法等,并提出了合理的线程数量配置策略,以平衡CPU利用率和线程切换开销。
面试官:单核 CPU 支持 Java 多线程吗?为什么?被问懵了!
|
1月前
|
存储 算法 Java
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
本文详解自旋锁的概念、优缺点、使用场景及Java实现。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
大厂面试高频:什么是自旋锁?Java 实现自旋锁的原理?
|
1月前
|
存储 缓存 Java
大厂面试必看!Java基本数据类型和包装类的那些坑
本文介绍了Java中的基本数据类型和包装类,包括整数类型、浮点数类型、字符类型和布尔类型。详细讲解了每种类型的特性和应用场景,并探讨了包装类的引入原因、装箱与拆箱机制以及缓存机制。最后总结了面试中常见的相关考点,帮助读者更好地理解和应对面试中的问题。
53 4
|
2月前
|
算法 Java 数据中心
探讨面试常见问题雪花算法、时钟回拨问题,java中优雅的实现方式
【10月更文挑战第2天】在大数据量系统中,分布式ID生成是一个关键问题。为了保证在分布式环境下生成的ID唯一、有序且高效,业界提出了多种解决方案,其中雪花算法(Snowflake Algorithm)是一种广泛应用的分布式ID生成算法。本文将详细介绍雪花算法的原理、实现及其处理时钟回拨问题的方法,并提供Java代码示例。
89 2