首页 > 编程语言 >剑指offer面试题21(java版):调整数组顺序使奇数位于偶数前面

剑指offer面试题21(java版):调整数组顺序使奇数位于偶数前面

时间:2023-01-18 10:37:59浏览次数:68  
标签:面试题 java 21 int arr ++ pEnd array pStart


​welcome to my blog​

剑指offer面试题21(java版):调整数组顺序使奇数位于偶数前面

题目描述

输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。

第三次做; 模拟快排的partition过程, 时间复杂度O(N),空间复杂度O(1)

//模拟一遍partition的过程, pivot是奇数; 时间复杂度O(N), 空间复杂度O(1)
class Solution {
public int[] exchange(int[] nums) {
//input check
if(nums==null || nums.length<2)
return nums;
int n=nums.length, small = -1, big=n, p=0;
while(p<big){
if(nums[p]%2==1)
swap(nums, ++small, p++);
else
swap(nums, --big, p);
}
return nums;
}
private void swap(int[] arr, int i, int j){
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}

笔记

  • 数组问题, 输入的数组长度可以为0, 这并不是异常
  • java中函数能作为参数吗? (试试内部类)

第二次做 利用了归并排序的思想 注意while下如何保证稳定性; 使用归并排序时我有个疑惑,就是如果arr[p1]和arr[p2]都是偶数怎么办? 我当时担心这两个偶数后面还有奇数, 其实如果arr[p1]和arr[p2]都是偶数, 说明p1,p2后面的元素也都是偶数!, 看来递归的过程理解的还不到位

  • 不是最优解, 时间复杂度O(NlogN) 空间复杂度O(N)
/*
保证相对位置不变, 得用类似稳定排序的思想
归并,冒泡,插入
*/
public class Solution {
public void reOrderArray(int [] array) {
if(array==null || array.length<2) return;
mergeSort(array, 0, array.length-1);
}
public void mergeSort(int[] arr, int left, int right){
//base case
if(left==right) return;
//
int mid = left + ((right-left)>>1);
mergeSort(arr, left, mid);
mergeSort(arr, mid+1, right);
merge(arr, left, mid, right);
}
public void merge(int[] arr, int left, int mid, int right){
int[] help = new int[right - left + 1];
int p1=left, p2=mid+1, i=0;
while(p1<=mid && p2<=right){
//注意如何保持相对位置不变
//必须先判断p1,再判断p2
if((arr[p1]&1)==1)
help[i++] = arr[p1++];
else if((arr[p2]&1)==1)
help[i++] = arr[p2++];
else
help[i++] = arr[p1++];
}
while(p1<=mid)
help[i++] = arr[p1++];
while(p2<=right)
help[i++] = arr[p2++];
for(int k=0; k<help.length; k++)
arr[left++] = help[k];
}
}

第二次做 最优解(并非最优解, 最优解应该是使用partition的方法) 时间复杂度和空间复杂度都是O(N)

public class Solution {
public void reOrderArray(int [] array) {
if(array==null||array.length<2)return;
int[] even = new int[array.length];
int oddIndex=0, evenIndex=0;
for(int i=0; i<array.length; i++){
if((array[i]&1)==0)
even[evenIndex++] = array[i];
else
array[oddIndex++] = array[i];
}
evenIndex=0;
for(int i=oddIndex; i<array.length; i++)
array[i] = even[evenIndex++];
}
}

下面这段代码没有保证奇数和奇数, 偶数和偶数之间的相位置对会改变,如2,2,1

public class Solution {
public void reOrderArray(int [] array) {
// input check
if(array.length < 1)
throw new RuntimeException("invalid input");
// execute
int pStart = 0;
int pEnd = array.length - 1;
while(pStart < pEnd){
while(pStart < pEnd && array[pStart]%2==1) // 当array[pStart]能够待在数组靠前的部分时,向后移动pStart,直到array[pStart]不能待在数组的靠前部分
pStart++;
while(pStart < pEnd && array[pEnd]%2==0) // 当array[pEnd]能够待在数组靠后的部分时,向前移动pEnd,直到array[pEnd]不能待在数组的靠后部分
pEnd--;
if(pStart < pEnd){
int temp = array[pStart];
array[pStart] = array[pEnd];
array[pEnd] = temp;
}
}
}
}

保证奇数和奇数, 偶数和偶数之间相对顺序的代码

public class Solution {
public void reOrderArray(int [] array) {
// input check 其实不用健壮性检查, 数组问题,可以输入长度为0的数组!
//if(array.length < 1)
// return null;

// execute
int oddCnt =0;
int evenCnt = 0;
int[] arrayEven = new int[array.length];
for(int i=0; i<array.length; i++){
if(array[i]%2==1)
array[oddCnt++] = array[i];
else
arrayEven[evenCnt++] = array[i];
}
evenCnt = 0;
for(int i=oddCnt; i<array.length; i++) // oddCnt是第一个偶数的索引
array[i] = arrayEven[evenCnt++];
}
}

一个.java中只能有一个public class

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-wBsRCRLC-1582115390880)(WEBRESOURCE71d4e50de6235f90254813e3137fafcc)]


标签:面试题,java,21,int,arr,++,pEnd,array,pStart
From: https://blog.51cto.com/u_2420922/6019019

相关文章

  • Java8中Map函数应用
    computeIfAbsent函数computeIfAbsent方法的逻辑是,如果map中没有(Absent)相应的key,则执行lambda表达式生成一个默认值并放入map中并返回,否则返回map中已有的值。List<......
  • 【转】Java项目构建工具Gradle是否可以完全替代Maven?
    前言在Java项目的开发中,需要引入自动化构建工具来帮助我们管理项目的外部依赖包、项目编译、打包等工作。Gradle和Maven是Java世界中两个重要的自动化构建工具,在项目中我们......
  • S2 - Lesson 21 - Mad or not?
    Wordsmaddrivesb.madbemadgetmad sum reasonforsomereasonforsomereasonsfornoreason determinedbedeterminedtodosth.      ......
  • 【Javaweb】servlet一
    什么是servlet1、servlet是JavaEE规范之一,规范就是接口。2、servlet是Javaweb三大组件之一。三大组件分别是:servlet程序、filter过滤器、listener监听器。3、servlet是......
  • JavaWeb项目中web.xml配置文件<servlet-class>…</servlet-class>中的路径出现问题以及服
    问题如图 原因:1.改变了WEB-INF文件夹下lib文件夹下servlet-api.jar的路径2.缺失lib文件夹下的servlet-api.jar,没有添加到库中解决办法:不要改动lib文件的路......
  • IDEA:自动生成方法注释并添加 @param 参数(Java+Kotlin)
    在用 Java 或 Kotlin 编写方法时建议编写完善的注释,包含每个参数的意义和返回的内容,下面介绍在 IDEA 中自动生成方法注释的技巧。    第二张图按照图片填写......
  • Java | Spring Boot数据源配置原理
    在数据库访问过程中,“数据源”无疑是最重要的概念之一,它不仅可以对与数据库访问相关的各种参数进行封装和统一管理,还可以管理数据库连接池,提高数据库连接性能。目前,在市面......
  • 汇总最近遇到的 Linux 面试题
    大家好啊,我是大田。今天汇总最近小伙伴遇到的Linux面试题你之前在公司使⽤linux命令做什么?搭建测试环境查看后台⽇志在之前公司,测试环境使⽤的是哪个linux版......
  • Java | Spring Boot统一日志框架
    在项目开发中,日志十分的重要,不管是记录运行情况还是定位线上问题,都离不开对日志的分析。在Java领域里存在着多种日志框架,如JCL、SLF4J、Jboss-logging、jUL、log4j、log......
  • Java 基础复习
    Java基础复习java常用转义字符1)\t一个制表位,实现对齐的功能2)\n换行符3)\\一个\4)\"一个"5)\'一个'6)\r一个回车注释单行注释//多行注释/**/文......