第2章 面试需要的基础知识
第3章 高质量的代码
面试题16:数值的整数次方
面试题21:调整数组顺序使奇数位于偶数前面
第4章 解决面试题的思路
第5章 优化时间和空间效率
第6章 面试中的各项能力
第7章 两个面试案例
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分。
解题思路
维护两个指针,第一个指针初始化时指向数组第一位,它只向后移动,第二个指针初始化时指向数组最后一位,它只向前移动。如果第一个指针指向的是偶数,第二个指针指向的是奇数,则交换两个数字,因此一次遍历即可完成。
实战
def reOrderArray(array):
# write code here
if not array:
return array
while odd < even:
while odd < even and array[odd] % 2 == 1:
odd += 1
while odd < even and array[even] % 2 == 0:
even -= 1
if odd < even:
array[odd], array[even] = array[even], array[odd]
return array
上题是《剑指offer》书中原题,在牛客网上有一道类似题目,不过加了一个条件,就是偶数与偶数之间,奇数与奇数之间相对位置不变,在此条件下,上述解法不可行。
题目描述
牛客网
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
解题思路
解法一:
最简单的就是使用辅助空间。建立两个数组,分别存放奇数和偶数,遍历一遍数组,即可区分所有奇偶数,最后合并两个数组并返回。显然这种解法并不能得到面试官的青睐
def reOrderArray(array):
# write code here
if not array:
return []
odd, even = [], []
for num in array:
if num % 2 == 1:
odd.append(num)
else:
even.append(num)
return odd + even
解法二:
使用O(1)空间。第一题的解法会导致元素之间相对位置打乱,原因在于遇到偶数在奇数前时就立即交换元素。其实改进交换时间即可保持相对位置不变。
冒泡排序中每遍历一遍都可将一个最大值或者最小值排序到位,我们可以借鉴冒泡排序思想,使用两个循环,外循环用于控制已移位的元素边界,内循环中每次都将未移位元素中最左边的奇数移位到最左边。
举例:
[1, 2, 8, 7, 6, 5]
- 初始化,指针begin,end分别指向1和5;
- 开始外循环,1为奇数,begin右移一位,begin指向2;
- 5是最右边的奇数,创建临时变量odd,指向5;
- 进入内循环,array[odd-1]是偶数,交换array[odd]和array[odd-1];
- 此时数组情况为:[1, 2, 8, 7, 5, 6],begin,end, odd分别指向2, 5, 5;
- 内循环中发现array[odd-1]=7是奇数,odd左移一位,end不变;
- array[odd-1]=8是偶数,交换array[odd]和array[odd-1],odd左移一位;
- array[odd-1]=2是偶数,交换array[odd]和array[odd-1],odd左移一位;
- 此时数组情况为:[1, 7, 2, 8, 5, 6],odd < begin,结束内循环;
- 继续下一次外循环。
上述过程中,第一次遇到偶数在奇数前面是array[begin]=2, array[end]=5,此时并没有立即交换元素,而是利用临时变量odd去寻找最左边的奇数,找到最左边奇数7,然后执行交换。
实战
class Solution:
def reOrderArray(self, array):
# write code here
if not array:
return[]
left, right = 0, len(array)-1
while left < right:
while array[left] % 2 == 1:
left += 1
while array[right] % 2 == 0:
right -= 1
if left < right:
odd = right
while odd > left:
if array[odd-1] % 2 == 0:
array[odd], array[odd-1] = array[odd-1], array[odd]
odd -= 1
return array