LeetCode#905 - 按奇偶排序数组

题目

给定一个非负整数数组 A,返回一个由 A 的所有偶数元素组成的数组,后面跟 A 的所有奇数元素。

你可以返回满足此条件的任何数组作为答案。

输入:[3,1,2,4]

输出:[2,4,3,1]

输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受。

解题思路

根据题目的描述,我们可以看到这道题只有一个要求,那就是将数组中的偶数全部挪到奇数的前面,另外顺序不计。

解法一

我看到这个题的第一反应是可以使用插入排序来解决这个问题,插入排序主要使用两个for循环,一个用来遍历整条数组,另一个用来扫描已排好顺序的列,将元素插入到合适的位置,再使用if语句来判断是否满足两个元素交换的条件。

对于这道题两个元素交换的条件是当前索引位置的元素是偶数且它的前一个位置是奇数,于是有了第一种解法。

public static int[] SortArrayByParity(int[] A)
{
    int length = A.Length;
    for (int i = 1; i < length; i++)
    {
        for (int j = i; j > 0; j--)
         {
            if(A[j]%2==0&&A[j-1]%2==1) //当前索引位置元素是偶数且前一个位置是奇数
            {
                int temp = A[j];
                A[j] = A[j - 1];
                A[j - 1] = temp;
            }
        }
    }
     return A;
}

这种解法其实就是将简单插入排序的if语句换了一下而已。因为代码中只使用一个temp变量作为两个元素交换的‘中介’,所以它的空间复杂度为O(1),时间复杂度也就是简单插入排序的时间复杂度,即O(n^2),但是实际肯定要比插入排序快,因为题目并不要求有序。


解法二

第二种解法的思路是,创建一个A数组长度一样的数组B,同时新建两个索引变量ij。其中,i指向数组的第一个位置,j指向数组的最后一个位置。

程序开始对A进行遍历,遍历的同时对每个元素进行奇偶判断。如果是偶数,就把当前元素放在B[i]的位置,同时i自增1;如果是奇数,就放在B[j]的位置,同时j自减1。

public static int[] SortArrayByParity(int[] A)
{
    int length = A.Length;
    int[] B = new int[length];
    int i = 0, j = length-1;
    foreach (var item in A)
    {
        if(item%2==0)
        {
            B[i] = item;
             i++;
        }
        else
        {
            B[j] = item;
            j--;
        }
    }
    return B;
}

在第二种解法种,我们创建了和数组A一样长度的数组B,所以它的空间复杂度是O(n)。另外,我们只对数组A进行了一次遍历,所以时间复杂度是O(n)。

结语

在物理内存中,数组是一块连续的区域,元素是一个挨着一个的,就像火车车厢一样,我觉得这种对数组元素位置进行“重排”的题目,基本就两种解题思路:一种是挪动元素位置;另一种就是创建新数组,将旧数组中满足条件的元素重新插入新数组中。我在网上也有看到其他的解题方式,例如利用过滤器找出数组中的偶数和奇数,然后再将分解出来的偶数数组和奇数数据进行连接,我觉得本质上和第二种解法是一样的。

如果你还有更好的优化方法,欢迎在评论留言探讨。

原文地址:https://www.cnblogs.com/xscape/p/10204729.html

时间: 2024-08-30 01:49:24

LeetCode#905 - 按奇偶排序数组的相关文章

905. 按奇偶排序数组

给定一个非负整数数组 A,返回一个由 A 的所有偶数元素组成的数组,后面跟 A 的所有奇数元素. 你可以返回满足此条件的任何数组作为答案. 示例: 输入:[3,1,2,4] 输出:[2,4,3,1] 输出 [4,2,3,1],[2,4,1,3] 和 [4,2,1,3] 也会被接受. 提示: 1 <= A.length <= 5000 0 <= A[i] <= 5000 思路:  同时从头尾开始遍历,   目前 beat 100% class Solution { public in

LeetCode 81——搜索旋转排序数组 II

1. 题目 2. 解答 2.1. 方法一 基于 LeetCode 33--搜索旋转排序数组 中的方法二. 当 nums[mid] = nums[right] 时,比如 [1, 1, 2, 1, 1],[1, 1, 0, 1, 1],为了找到正确的转折点,我们查看 [mid, right] 之间有没有不等于 nums[mid] 的值,若有,则继续向右查找:否则向左查找. class Solution { public: int Binary_Search(vector<int>& num

按奇偶排序数组

export default (arr) => { // 进行升序排序 arr.sort((a, b) => a - b) // 声明一个空数组用来存储奇偶排序后的数组 let r = [] // 记录奇数.偶数位下标 let odd = 1 let even = 0 // 对数组进行遍历 arr.forEach(item => { if (item % 2 === 1) { r[odd] = item odd += 2 } else { r[even] = item even += 2

[leetcode] 33. 搜索旋转排序数组(Java)

33. 搜索旋转排序数组 说实话这题我连题都没有看懂....真是醉了 二分,没意思,直接交了- - https://www.jiuzhang.com/solutions/search-in-rotated-sorted-array/#tag-other 原文地址:https://www.cnblogs.com/acbingo/p/9302337.html

【LeetCode】26. 删除排序数组中的重复项

题目 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度.不要使用额外的数组空间,你必须在原地修改输入数组并在使用 O(1) 额外空间的条件下完成. 示例1: 给定数组 nums = [1,1,2], 函数应该返回新的长度 2, 并且原数组 nums 的前两个元素被修改为 1, 2. 你不需要考虑数组中超出新长度后面的元素. 示例2: 给定 nums = [0,0,1,1,1,2,2,3,3,4], 函数应该返回新的长度 5, 并且原数组 nums

【LeetCode】34. 在排序数组中查找元素的第一个和最后一个位置

题目 给定一个按照升序排列的整数数组 nums,和一个目标值 target.找出给定目标值在数组中的开始位置和结束位置. 你的算法时间复杂度必须是?O(log n) 级别. 如果数组中不存在目标值,返回?[-1, -1]. 示例 1: 输入: nums = [5,7,7,8,8,10], target = 8 输出: [3,4] 示例?2: 输入: nums = [5,7,7,8,8,10], target = 6 输出: [-1,-1] 本题同[剑指Offer]面试题53 - I. 在排序数组

力扣(LeetCode)922. 按奇偶排序数组 II

给定一个非负整数数组 A, A 中一半整数是奇数,一半整数是偶数. 对数组进行排序,以便当 A[i] 为奇数时,i 也是奇数:当 A[i] 为偶数时, i 也是偶数. 你可以返回任何满足上述条件的数组作为答案. 示例: 输入:[4,2,5,7] 输出:[4,5,2,7] 解释:[4,7,2,5],[2,5,4,7],[2,7,4,5] 也会被接受. 提示: 2 <= A.length <= 20000 A.length % 2 == 0 0 <= A[i] <= 1000 思路 遍

LeetCode 922. Sort Array By Parity II (按奇偶排序数组 II)

题目标签:Sort 利用两个指针,在偶数位置上找到第一个奇数:在奇数位置上找到第一个偶数,然后互相转换数字. 具体看code. Java Solution: Runtime:  2ms, faster than 99.61% Memory Usage: 42.9MB, less than 29.63% 完成日期:03/06/2020 关键点:two pointers class Solution { public int[] sortArrayByParityII(int[] A) { int

领扣(LeetCode)寻找旋转排序数组中的最小值 个人题解

假设按照升序排序的数组在预先未知的某个点上进行了旋转. ( 例如,数组 [0,1,2,4,5,6,7] 可能变为 [4,5,6,7,0,1,2] ). 请找出其中最小的元素. 你可以假设数组中不存在重复元素. 示例 1: 输入: [3,4,5,1,2] 输出: 1 示例 2: 输入: [4,5,6,7,0,1,2] 输出: 0 这题拿到手发现很简单..实际上也的确比较简单.我以为会挖个什么坑在等我,但是只要使用遍历数组的办法找到下一个值比上一个小的地方,输出后值就是答案.这样做的时间复杂度是O(