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

题目:输入一个整数数组,实现一个函数来解决该数组中数字的位置,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。

本题思路较为简单,我们只需维护两个指针:第一个指针pHead 初始化为数组的第一个元素,第二个指针pTail 初始化为数组的最后一个元素。根据题目要求:所有奇数位于数组的前半部分,偶数位于数组的后半部分;我们只需:

1、使指针pHead 向后遍历,直到指向的整数为偶数;

2、使指针pTail 向前遍历,直到指向的整数为奇数;

3、交换指针pHead 和指针pTail 所指向的元素。

4、在 pHead 和 pTail 相遇之前,pHead继续向后遍历,pTail继续向前遍历。

实现代码为:

 1 #include "stdio.h"
 2 #include "stdlib.h"
 3
 4 #define N 10
 5
 6 void swap(int *left, int *right);
 7 void printArr(int *arr, int len);
 8 void initArr(int *arr, int len);
 9 void reorderOddEven(int *arr, int len);
10
11 void swap(int *left, int *right)
12 {
13     int tmp = *left;
14     *left = *right;
15     *right = tmp;
16 }
17
18 void printArr(int *arr, int len)
19 {
20     int i;
21     for(i = 0; i < len; ++i)
22     {
23         printf("%3d", arr[i]);
24     }
25     printf("\n");
26 }
27
28 void initArr(int *arr, int len)
29 {
30     int i;
31     for(i = 0; i < len; ++i)
32     {
33         arr[i] = rand() %100;
34     }
35 }
36
37 void reorderOddEven(int *arr, int len)
38 {
39     int *pHead = arr;
40     int *pTail = arr + len -1;
41
42     while(pHead < pTail)
43     {
44         while(pHead < pTail && (*pHead & 0x1) != 0)
45             pHead++;
46
47         while(pHead < pTail && (*pTail & 0x1) == 0)
48             pTail--;
49
50         if(pHead < pTail)
51             swap(pHead, pTail);
52     }
53 }
54
55 int main(int argc, char const *argv[])
56 {
57     int arr[N] = {0};
58     initArr(arr, N);
59     printf("Before: ");
60     printArr(arr, N);
61
62     reorderOddEven(arr, N);
63     printf("After: ");
64     printArr(arr, N);
65
66     return 0;
67 }

引入函数指针:

试考虑把题目改成如下情形:
1、把数组中的数按照大小分为两部分,所有负数都在非负数的前面,该怎么做?
2、把数组中的数分成两部分,能被 3 整除的数都在不能被 3 整除的数的前面。该怎么办?

实际上,上面两个问题是我们在开端那个题目的变形,只需改变 while 循环里的条件即可。因此我们可以把这个条件的逻辑框架抽象出来,而把判断的标准变成一个函数指针,也就是用一个单独的函数来判断数字是不是符合条件。因此上面的条件可以变成两个函数来解决:

1 bool isNegative(int n);
2 bool is3Multi(int n);

而上面的问题:把所有奇数排在偶数前面的问题,我们就可以用下面函数解决:

bool isEven(int n)
{
    return (n & 0x1) == 0;
}

完整的代码如下:

 1 // reorderOddEven.cpp
 2 #include "stdio.h"
 3 #include "stdlib.h"
 4
 5 #define N 10
 6
 7 void reorderOddEven(int *arr, int len);
 8 void Reorder(int *pData, unsigned int length, bool (*func)(int));
 9 bool isEven(int n);
10
11 void swap(int *left, int *right)
12 {
13     int tmp = *left;
14     *left = *right;
15     *right = tmp;
16 }
17
18 void printArr(int *arr, int len)
19 {
20     int i;
21     for(i = 0; i < len; ++i)
22     {
23         printf("%3d", arr[i]);
24     }
25     printf("\n");
26 }
27
28 void initArr(int *arr, int len)
29 {
30     int i;
31     for(i = 0; i < len; ++i)
32     {
33         arr[i] = rand() % 100;
34     }
35 }
36
37 void reorderOddEven(int *arr, int len)
38 {
39     if(!arr || len <= 0)
40         return;
41
42     Reorder(arr, len, isEven);
43 }
44
45 void Reorder(int *pData, unsigned int length, bool (*func)(int))
46 {
47     int *pBegin = pData;
48     int *pEnd = pData + length - 1;
49
50     while(pBegin < pEnd)
51     {
52         // 向后移动pBegin
53         while(pBegin < pEnd && !func(*pBegin))
54             pBegin ++;
55
56         // 向前移动pEnd
57         while(pBegin < pEnd && func(*pEnd))
58             pEnd --;
59
60         if(pBegin < pEnd)
61             swap(pBegin, pEnd);
62     }
63 }
64
65 bool isEven(int n)
66 {
67     return (n & 0x1) == 0;
68 }
69
70 int main(int argc, char const *argv[])
71 {
72     int arr[N] = {0};
73     initArr(arr, N);
74     printf("Before: ");
75     printArr(arr, N);
76
77     reorderOddEven(arr, N);
78     printf("After: ");
79     printArr(arr, N);
80
81     return 0;
82 }

本文完。

时间: 2024-10-12 15:46:35

【剑指offer】面试题14、调整数组顺序使奇数位于偶数前面的相关文章

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

def isOdd(n): return n & 1 def Reorder(data, cf = isOdd): odd = 0 even = len( data ) - 1 while True: while not isOdd( data[ even ]) : even -= 1 while isOdd( data[ odd ]) : odd += 1 if odd >= even: break data[ even ], data[ odd ] = data[ odd ], data

《剑指Offer》题目:调整数组顺序使奇数位于偶数前面

题目描述:调整数组顺序使奇数位于偶数前 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 题目分析: 题目的关键在于在移位以后,奇数和奇数以及偶数和偶数之间的相对位置保持不变. Java代码: public class ReOrderArray { //这种方法不能保证奇数和奇数,偶数和偶数之间的相对位置不变 public static void reOrderArray(

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

题目描述 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变. 分析:此题在oj上练习时多加了条件,即调整后的数字之间的顺序是不变的.目前只想到一种方法,后续有其他方法再做添加.新建一个数组,扫描原数组两遍,第一遍取出原数组中所有的奇数,存入新数组中.第二遍找出所有的偶数存入新数组中.代码实现如下: 1 public class Solution { 2 public void

剑指offer_面试题14_调整数组顺序使奇数位于偶数前面(函数指针用法)

题目:输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分. 1.一般想法,不考虑时间复杂度: 每次遍历数组,碰到一个偶数就拿出来,将后面所有数字向前挪动一位,在将该偶数放到最后. 2.利用冒泡排序的思想,两个指针,一前以后,如果前为偶数,后为奇数,就交换. 算法如下: void Reorder_array(int p[],int length) { if(NULL == p || length <= 0) return; int i

面试题 14:调整数组顺序使奇数位于偶数前面

使用两个指针,在数组头尾相对移动: 循环结束条件:头和尾重叠活着头在尾之后 左边指针右移条件:当前数是奇数 右边指针左移条件:当前数是偶数 当且仅当左边指针是偶数,右边指针是奇数,交换两个指针的值 此题注意扩展,函数功能的重用. package offer; import java.util.Arrays; /*面试题 14:调整数组顺序使奇数位于偶数前面 题目:输入一个整数数组,实现一个函数来调整该函数数组中数字的顺序,使得所有奇数位于数组的前半部分,所有的数组位于数组的后半部分.*/ pub

面试题14:调整数组顺序使奇数位于偶数前面

// 面试题14_调整数组顺序使奇数位于偶数前面.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream> using namespace std; void swap(int *begin,int *end) { int temp; temp=*begin; *begin=*end; *end=temp; } void ReorderOddEven(int *pData,unsigned int len

剑指offer编程题Java实现——面试题14调整数组顺序使奇数位于偶数之前

题目: 输入一个整数数组,实现一个函数来调整该数组中数组的顺序,使得所有的奇数位于数组的前半部分,偶数位于数组的后半部分. 解题思路:数组中维护两个指针,第一个指针初始化时候指向数组头部,第二个指针初始化时候指向数组尾部,第一个指针指向的数字总是偶数,第二个指针指向的数字总是奇数,如果第一个指针在第二个指针之前,则交换两指针指向的元素. 1 package Solution; 2 3 /** 4 * 剑指offer面试题14:调整数组顺序是奇数位于偶数前面 5 * 题目:输入一个整数数组,实现一

剑指offer-面试题14.调整数组顺序使奇数位于偶数的前面

题目:输入一个整数数组,实现一个函数来调整该数组中的数字的顺序, 使得所有的奇数位于数组的前半部门,所有的偶数位于数组的后半部门. 这一题一看其实是很简单的,当然在不考虑效率的情况可以这样考虑 我们将数组从前开始索引只要发现偶数这将偶数取出来并且将偶数后 面的元素全部前移一个然后将偶数插入到最后,这样扫描一遍之后 就将偶数全部放在了后半部门,奇数放在了前半部分.但是效率不好 每次遇到偶数都要移动偶数后面的所有元素再加上遍历数组的时间 则达到了O(n2) 我们可以用两个索引或者指针,一个指向数组的

剑指offer 面试14—调整数组顺序使奇数位于偶数前面

题目: 输入一个整数数组,实现一个函数来调整该数组中数组的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分. 解法一:O(n^2) 从头扫描数组,每碰到一个偶数,拿出这个数字,并把位于这个数字后面的所有数字往前挪动一位.挪完之后在数组的末尾有一个空位,这时把该偶数放入这个空位中. 由于每碰到一个偶数就需要移动O(n)个数字,因此总的时间复杂度是O(n^2). 解法二:O(n) 类似快排,两个指针,一个指向数组头,只向后移动,一个指向数组尾,只向前移动.如果第一个指针指向的数字是偶

【剑指Offer】面试题21. 调整数组顺序使奇数位于偶数前面

题目 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分. 示例: 输入:nums =?[1,2,3,4] 输出:[1,3,2,4] 注:[3,1,2,4] 也是正确的答案之一. 提示: 1 <= nums.length <= 50000 1 <= nums[i] <= 10000 思路 代码 时间复杂度:O(n) 空间复杂度:O(1) class Solution { public: vector<int>