數(shù)據(jù)結(jié)構(gòu)與算法之按奇偶排序數(shù)組II
一道簡(jiǎn)單模擬題,來做做看!
按奇偶排序數(shù)組II
力扣題目鏈接:https://leetcode-cn.com/problems/sort-array-by-parity-ii/
給定一個(gè)非負(fù)整數(shù)數(shù)組 A, A 中一半整數(shù)是奇數(shù),一半整數(shù)是偶數(shù)。
對(duì)數(shù)組進(jìn)行排序,以便當(dāng) A[i] 為奇數(shù)時(shí),i 也是奇數(shù);當(dāng) A[i] 為偶數(shù)時(shí), i 也是偶數(shù)。
你可以返回任何滿足上述條件的數(shù)組作為答案。
示例:
- 輸入:[4,2,5,7]
- 輸出:[4,5,2,7]
- 解釋:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也會(huì)被接受。
思路
這道題目直接的想法可能是兩層for循環(huán)再加上used數(shù)組表示使用過的元素。這樣的的時(shí)間復(fù)雜度是O(n^2)。
方法一
其實(shí)這道題可以用很樸實(shí)的方法,時(shí)間復(fù)雜度就就是O(n)了,C++代碼如下:
- class Solution {
- public:
- vector<int> sortArrayByParityII(vector<int>& A) {
- vector<int> even(A.size() / 2); // 初始化就確定數(shù)組大小,節(jié)省開銷
- vector<int> odd(A.size() / 2);
- vector<int> result(A.size());
- int evenIndex = 0;
- int oddIndex = 0;
- int resultIndex = 0;
- // 把A數(shù)組放進(jìn)偶數(shù)數(shù)組,和奇數(shù)數(shù)組
- for (int i = 0; i < A.size(); i++) {
- if (A[i] % 2 == 0) even[evenIndex++] = A[i];
- else odd[oddIndex++] = A[i];
- }
- // 把偶數(shù)數(shù)組,奇數(shù)數(shù)組分別放進(jìn)result數(shù)組中
- for (int i = 0; i < evenIndex; i++) {
- result[resultIndex++] = even[i];
- result[resultIndex++] = odd[i];
- }
- return result;
- }
- };
- 時(shí)間復(fù)雜度:O(n)
- 空間復(fù)雜度:O(n)
方法二
以上代碼我是建了兩個(gè)輔助數(shù)組,而且A數(shù)組還相當(dāng)于遍歷了兩次,用輔助數(shù)組的好處就是思路清晰,優(yōu)化一下就是不用這兩個(gè)輔助樹,代碼如下:
- class Solution {
- public:
- vector<int> sortArrayByParityII(vector<int>& A) {
- vector<int> result(A.size());
- int evenIndex = 0; // 偶數(shù)下表
- int oddIndex = 1; // 奇數(shù)下表
- for (int i = 0; i < A.size(); i++) {
- if (A[i] % 2 == 0) {
- result[evenIndex] = A[i];
- evenIndex += 2;
- }
- else {
- result[oddIndex] = A[i];
- oddIndex += 2;
- }
- }
- return result;
- }
- };
- 時(shí)間復(fù)雜度O(n)
- 空間復(fù)雜度O(n)
方法三
當(dāng)然還可以在原數(shù)組上修改,連result數(shù)組都不用了。
- class Solution {
- public:
- vector<int> sortArrayByParityII(vector<int>& A) {
- int oddIndex = 1;
- for (int i = 0; i < A.size(); i += 2) {
- if (A[i] % 2 == 1) { // 在偶數(shù)位遇到了奇數(shù)
- while(A[oddIndex] % 2 != 0) oddIndex += 2; // 在奇數(shù)位找一個(gè)偶數(shù)
- swap(A[i], A[oddIndex]); // 替換
- }
- }
- return A;
- }
- };
- 時(shí)間復(fù)雜度:O(n)
- 空間復(fù)雜度:O(1)
這里時(shí)間復(fù)雜度并不是O(n^2),因?yàn)榕紨?shù)位和奇數(shù)位都只操作一次,不是n/2 * n/2的關(guān)系,而是n/2 + n/2的關(guān)系!
其他語言版本
Java
- // 方法一
- class Solution {
- public int[] sortArrayByParityII(int[] nums) {
- // 分別存放 nums 中的奇數(shù)、偶數(shù)
- int len = nums.length;
- int evenIndex = 0;
- int oddIndex = 0;
- int[] even = new int[len / 2];
- int[] odd = new int[len / 2];
- for (int i = 0; i < len; i++) {
- if (nums[i] % 2 == 0) {
- even[evenIndex++] = nums[i];
- } else {
- odd[oddIndex++] = nums[i];
- }
- }
- // 把奇偶數(shù)組重新存回 nums
- int index = 0;
- for (int i = 0; i < even.length; i++) {
- nums[index++] = even[i];
- nums[index++] = odd[i];
- }
- return nums;
- }
- }
Python3
- #方法2
- class Solution:
- def sortArrayByParityII(self, nums: List[int]) -> List[int]:
- result = [0]*len(nums)
- evenIndex = 0
- oddIndex = 1
- for i in range(len(nums)):
- if nums[i] % 2: #奇數(shù)
- result[oddIndex] = nums[i]
- oddIndex += 2
- else: #偶數(shù)
- result[evenIndex] = nums[i]
- evenIndex += 2
- return result
- #方法3
- class Solution:
- def sortArrayByParityII(self, nums: List[int]) -> List[int]:
- oddIndex = 1
- for i in range(0,len(nums),2): #步長(zhǎng)為2
- if nums[i] % 2: #偶數(shù)位遇到奇數(shù)
- while nums[oddIndex] % 2: #奇數(shù)位找偶數(shù)
- oddIndex += 2
- nums[i], nums[oddIndex] = nums[oddIndex], nums[i]
- return nums
Go
- // 方法一
- func sortArrayByParityII(nums []int) []int {
- // 分別存放 nums 中的奇數(shù)、偶數(shù)
- even, odd := []int{}, []int{}
- for i := 0; i < len(nums); i++ {
- if (nums[i] % 2 == 0) {
- even = append(even, nums[i])
- } else {
- odd = append(odd, nums[i])
- }
- }
- // 把奇偶數(shù)組重新存回 nums
- result := make([]int, len(nums))
- index := 0
- for i := 0; i < len(even); i++ {
- result[index] = even[i]; index++;
- result[index] = odd[i]; index++;
- }
- return result;
- }
JavaScript
- //方法一
- var sortArrayByParityII = function(nums) {
- const n = nums.length;
- // 分別存放 nums 中的奇數(shù)、偶數(shù)
- let evenIndex = 0, oddIndex = 0;
- // 初始化就確定數(shù)組大小,節(jié)省開銷
- const even = new Array(Math.floor(n/2));
- const odd = new Array(Math.floor(n/2));
- // 把A數(shù)組放進(jìn)偶數(shù)數(shù)組,和奇數(shù)數(shù)組
- for(let i = 0; i < n; i++){
- if(nums[i] % 2 === 0) even[evenIndex++] = nums[i];
- else odd[oddIndex++] = nums[i];
- }
- // 把奇偶數(shù)組重新存回 nums
- let index = 0;
- for(let i = 0; i < even.length; i++){
- nums[index++] = even[i];
- nums[index++] = odd[i];
- }
- return nums;
- };
- //方法二
- var sortArrayByParityII = function(nums) {
- const n = nums.length;
- const result = new Array(n);
- // 偶數(shù)下標(biāo) 和 奇數(shù)下標(biāo)
- let evenIndex = 0, oddIndex = 1;
- for(let i = 0; i < n; i++){
- if(nums[i] % 2 === 0) {
- result[evenIndex] = nums[i];
- evenIndex += 2;
- } else {
- result[oddIndex] = nums[i];
- oddIndex += 2;
- }
- }
- return result;
- };
- //方法三
- var sortArrayByParityII = function(nums) {
- let oddIndex = 1;
- for(let i = 0; i < nums.length; i += 2){
- if(nums[i] % 2 === 1){ // 在偶數(shù)位遇到了奇數(shù)
- while(nums[oddIndex] % 2 !== 0) oddIndex += 2;// 在奇數(shù)位找一個(gè)偶數(shù)
- [nums[oddIndex], nums[i]] = [nums[i], nums[oddIndex]]; // 解構(gòu)賦值交換
- }
- }
- return nums;
- };