算法笔记_049:奇偶数排序(Java)

目录

1 问题描述

2 解决方案

2.1 一头一尾指针往中间扫描法

2.2 一前一后两个指针同时往后扫描法

 


1 问题描述

给定一个整数数组,请调整 数组中数的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分。要求时间复杂度为O(n)。


2 解决方案

2.1 一头一尾指针往中间扫描法 

具体代码如下:

package com.liuzhen.array_2;

public class OddEvenSort {
    //解法1:一头一尾指针往中间扫描
    public void getOddEvenSort1(int[] A){
        if(A.length == 1)
            return;
        int begin = 0;
        int end = A.length - 1;
        while(begin < end){
            if(A[begin] % 2 == 1)   //当A[begin]为奇数时
                begin++;
            else if(A[end] % 2 == 0) //当A[end] 为偶数时
                end--;
            else                 //当A[begin]不是奇数且A[end]不是偶数时
                swap(A,begin,end);
        }
    }

    //交换数组A的m位置和n位置上的值
    public void swap(int[] A,int m,int n){
        int temp = A[m];
        A[m] = A[n];
        A[n] = temp;
    }

    public static void main(String[] args){
        OddEvenSort test = new OddEvenSort();
        int[] A = {2,1,4,7,1,4,7,1,2,8,4,3,6,7,2,14,3,7,4,3,2,4,3,2,7};
        test.getOddEvenSort1(A);
        System.out.println("使用方法1:一头一尾指针往中间扫描结果:");
        for(int i = 0;i < A.length;i++)
            System.out.print(A[i]+" ");
    }
}

运行结果:

使用方法1:一头一尾指针往中间扫描结果:
7 1 3 7 1 3 7 1 7 3 7 3 6 4 2 14 8 2 4 4 2 4 4 2 2 

2.2 一前一后两个指针同时往后扫描法

具体代码如下:

package com.liuzhen.array_2;

public class OddEvenSort {
    //解法2:一前一后两指针往后扫描
    public void getOddEvenSort2(int[] A){
        if(A.length == 1)
            return;
        int origin = 0;   //定义标准元素位置,最终结果是在该元素值的左边都是奇数,在该元素值的右边都是偶数
        int i = 0;
        for(int j = 1;j < A.length;j++){
            if(A[j] % 2 == 1){   //当A[j]为奇数时,右移一位,并交换A[i]和A[j]值,表明在i的左边均为奇数
                i++;
                swap(A,i,j);
            }
        }
        swap(A,i,origin);
    }

    //交换数组A的m位置和n位置上的值
    public void swap(int[] A,int m,int n){
        int temp = A[m];
        A[m] = A[n];
        A[n] = temp;
    }

    public static void main(String[] args){
        OddEvenSort test = new OddEvenSort();
        int[] B = {2,1,4,7,1,4,7,1,2,8,4,3,6,7,2,14,3,7,4,3,2,4,3,2,7};
        test.getOddEvenSort2(B);
        System.out.println("\n使用方法2:一前一后两指针往后扫描结果:");
        for(int i = 0;i < B.length;i++)
            System.out.print(B[i]+" ");
    }
} 

运行结果:

使用方法2:一前一后两指针往后扫描结果:
7 1 7 1 7 1 3 7 3 7 3 3 2 4 2 14 2 8 4 4 2 4 4 2 6 

参考资料:

1.编程之法面试和算法心得  July著

时间: 2024-10-19 18:26:36

算法笔记_049:奇偶数排序(Java)的相关文章

数据结构与算法笔记(3) 排序算法基础

1.什么是排序 排序就是将一个数据元素(或记录)的任意序列,通过一定的方法重新排列成一个按关键字有序的序列的过程. 2.排序的稳定性 假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,ri=rj,且ri在rj之前,而在排序后的序列中,ri仍在rj之前,则称这种排序算法是稳定的:否则称为不稳定的. 稳定的排序的优点是,从一个键上排序,然后再从另一个键上排序,第一个键排序的结果可以为第二个键排序所用. 例如,假设一个班的学生已经按照学号大

算法笔记_148:有向图欧拉回路求解(Java)

目录 1 问题描述 2 解决方案   1 问题描述 Description A catenym is a pair of words separated by a period such that the last letter of the first word is the same as the last letter of the second. For example, the following are catenyms: dog.gopher gopher.rat rat.tige

算法笔记_132:最大流量问题(Java)

目录 1 问题描述 2 解决方案   1 问题描述 何为最大流量问题? 给定一个有向图,并为每一个顶点设定编号为0~n,现在求取从顶点0(PS:也可以称为源点)到顶点n(PS:也可以称为汇点)后,顶点n能够接收的最大流量.图中每条边的权值为该边的容量,从顶点0到顶点n的某一条路径中最大流量不能超过该路径中任何一条边剩下的容量. 2 解决方案 上述对于最大流量问题的描述是楼主自己个人描述,描述的有点粗暴简略>~<. 求取最大流量问题的的核心要理解三个概念: (1)残留网络 (2)增广路径 (3)

算法笔记_124:密码脱落(Java)

一 问题描述 X星球的考古学家发现了一批古代留下来的密码.这些密码是由A.B.C.D 四种植物的种子串成的序列.仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串).由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征. 你的任务是:给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子. 输入一行,表示现在看到的密码串(长度不大于1000)要求输出一个正整数,表示至少脱落了多少个种子. 例如,输入:ABCBA则程序应该输出:0 再例

数组奇偶数排序

给定一个数组input[] ,如果数组长度n为奇数,则将数组中最大的元素放到 output[] 数组最中间的位置,如果数组长度n为偶数,则将数组中最大的元素放到 output[] 数组中间两个位置偏右的那个位置上,然后再按从大到小的顺序,依次在第一个位置的两边,按照一左一右的顺序,依次存放剩下的数. 例如:input[] = {3, 6, 1, 9, 7} output[] = {3, 7, 9, 6, 1}; input[] = {3, 6, 1, 9, 7, 8} output[] = {1

算法笔记_027:俄式乘法(Java)

1 问题描述 首先,了解一下何为俄式乘法?此处,借用<算法设计与分析基础>第三版上一段文字介绍: 2 解决方案 具体编码如下: package com.liuzhen.chapter4; public class RussianPeasant { //方法1:递归求解 public void recursionRussian(int m,int n,int result){ if(m < 1) return; if(m == 1) System.out.println("使用递

算法笔记_016:凸包问题(Java)

目录 1 问题描述 2 解决方案 2.1 蛮力法 1 问题描述 给定一个平面上n个点的集合,它的凸包就是包含所有这些点的最小凸多边形,求取满足此条件的所有点. 另外,形象生动的描述: (1)我们可以把这个问题看作如何用长度最短的栅栏把n头熟睡的老虎围起来. (2)也可以这样看:请把所讨论的点想象成钉在胶合板上的钉子,胶合板代表平面.撑开一根橡皮筋圈,把所有的钉子都围住,然后啪一声松开手.凸包就是以橡皮圈为边界的区域.具体示意如下图1所示: 图1  用橡皮筋来解释凸包 2 解决方案 2.1 蛮力法

算法笔记_042:求最小公倍数(Java)

目录 1 问题描述 2 解决方案   1 问题描述 何为最小公倍数?能同时被数字m和数字n整除的最小整数.例如,24和60的最小公倍数等于120.下面请编写相关函数实现求取数字m和n的最小公倍数. 2 解决方案 关于本文求解最小公倍数的思想,来自于<算法设计与分析基础>第三版上一段讲解,具体如下: 具体代码如下: package com.liuzhen.chapter6; public class LeastCommonMultiple { //使用欧几里得算法求解数m和数n最大公约数 pub

算法笔记_225:数字密码发生器(Java)

目录 1 问题描述 2 解决方案   1 问题描述 在对银行账户等重要权限设置密码的时候,我们常常遇到这样的烦恼:如果为了好记用生日吧,容易被破解,不安全:如果设置不好记的密码,又担心自己也会忘记:如果写在纸上,担心纸张被别人发现或弄丢了... 这个程序的任务就是把一串拼音字母转换为6位数字(密码).我们可以使用任何好记的拼音串(比如名字,王喜明,就写:wangximing)作为输入,程序输出6位数字. 变换的过程如下: 第一步. 把字符串6个一组折叠起来,比如wangximing则变为: wa