个人评价:数组操作,尽量避免删除和插入操作,转换为值交换是个很好的优化手段~
题目难度:🌟🌟 (参考 LeeCode 简单🌟 、中等🌟 🌟 、困难🌟 🌟 🌟 )
另,通常算法题会考察分析时间复杂度和空间复杂度,可参考笔者之前的文章
调整数组顺序使奇数位于偶数前面
题目描述
输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。
示例:
输入:nums = [1,2,3,4]
输出:[1,3,2,4]
注:[3,1,2,4] 也是正确的答案之一。
提示:
0 <= nums.length <= 50000 1 <= nums[i] <= 10000
解题思路
方法一
此题保持空间复杂度O(1),直接在原数组上操作的方式不难。基础思路如下:
- 遍历数组,找到偶数(如下标 i),将其移至数组尾(相当于删除 nums[i] 再插入该值)
较基础,代码就不放了。时间复杂度?🙌 O(n²)
显然,时间复杂度有待提升,那就再想想~
方法二
数组元素移动的操作会增加复杂度,如果可以直接交换值,只需常量 O(1) 的时间复杂度。
那如何进行合理的值交换呢?我们可以引入双指针,思路如下:
- 从左向右的指针 i,如果找到偶数,停止
- 从右至左的指针 j,如果找到奇数,停止
- 两者进行交换,直至相遇(即 i<=j),完成整体置换
代码写法上各语言略有不同,但基本需要用到 continue 和 break,Go 代码参考如下:
func exchange(nums []int) []int {
j := len(nums)-1
for i := 0; i <= j ; i++ {
if nums[i]%2 != 0 {
continue
}
for j>i {
if nums[j]%2==1 {
nums[j], nums[i] = nums[i], nums[j] //go 两数交换~
break
}
j--
}
}
return nums
}
不难,但是能信手拈来直接写出👆代码还是很能体现功力的~
总结
数组操作还是比较常用的,通常面试,只想到方法一是万万不够的。
个人认为此题很适合面试,循环的 break 和 continue 都用上了哈~