Algorithm
题目: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
思路:使用双指针。
- 指针 i 用于遍历数组找出偶数的元素
- 指针 p 用于指向从左到右第一个奇数的元素(这里假设无论第一个元素是不是偶数都看作奇数)
- 当 i 找到偶数以后和 p 指向的元素交换(由于之前的假设,所以可能会发生第一个元素自己和自己交换),交换后 p 向后移动一位
实现代码:
class Solution {
public int[] sortArrayByParity(int[] A) {
int len = A.length;
int p = 0;
for (int i = 0; i < len; i++) {
if (A[i] % 2 == 0) {
swap(A, i, p++);
}
}
return A;
}
private void swap(int[] arr, int i, int j) {
int tmp = arr[i];
arr[i] = arr[j];
arr[j] = tmp;
}
}
注意:在定义swap
函数时,不要使用下面的方法!!!!!!!
private void swap(int[] arr, int i, int j) {
arr[i] = arr[i] ^ arr[j];
arr[j] = arr[i] ^ arr[j];
arr[i] = arr[i] ^ arr[j];
}
如果 0 和其他非零元素交换,这种交换方法会改变非零元素本身的值。
Review
最近在读 JVM 规范,这里列出了自己阅读第二章The Structure of the Java Virtual Machine前四节的一些以前不知道的知识。由于本人 Java 仅学习了一年,且英语水平较低,可能会有部分误解,望指正。
JVM 是通过指令集来识别基本数据类型的值的类型的,例如,iadd
指令操作两个int
型数值的求和,ladd
指令是针对long
型数值的求和 …
JVM 的基本类型除了有 Java 语言的八种基本数据类型,还有一种returnAddress
类型,该类型是指向 JVM 操作码的指针,这种类型与 Java 语言类型是没有直接关系的。
JVM 对于boolean
类型的支持有限,boolean
值会被编译器映射为 JVM 的int
值,其中 1 代表true
、0 代表false
,所以 JVM 中也没有专门用于操作boolean
值的指令,
浮点类型除了常见的非零值,还有正负零、正负无穷、NaN(通常代表无效操作,如 0/0 ) 这五个值。JVM 在进行浮点数运算时并不会抛出运行时异常,如:
System.out.println(1.0 / 0.0); // Infinity
System.out.println(-1.0 / 0.0); // -Infinity
System.out.println(-0.0 == 0.0); // true
System.out.println(0.0 / 0.0); // NaN
其中 NaN 是无序的,任何值(包括 NaN)与 NaN 的比较和相等测试的结果都是false
,且只有 NaN 与自身判断相等性时的结果是false
,基于此,在Float
类中有一个静态方法来判断某个浮点值是否为 NaN:
//在 Double 中也有一个类似的函数,当然,参数类型为 double
public static boolean isNaN(float v) {
return (v != v);
}
null
可以转化为任意类型!!这里列出了当时学习泛型时遇到的涉及该知识点的内容:
在泛型中,上界通配符<? extends T>
通常用于限制操作,不能使用在添加数据上面,一般都是对数据的读取操作。因为无法确定实参具体的类型具体是什么,add
方法受限(但是可以添加null
,null
表示任何类型),但可以从列表中获取元素后赋值给父类型。
@Test
//这里无法确定传过来的实参具体的泛型类型是什么,所以 add方法受限
public void test1(List<? extends Animal> list) {
//add方法类型均受限,无法判断子类型的具体类型。报错
list.add(new Animal());
list.add(new Dog());
list.add(new Cat());
//get不受限,可以取出复制给通配符的上界类型
Animal a = list.get(0);
//get类型受限,但是无法判断子类型的具体类型,不能进行转换。报错
Cat cat = list.get(0);
}
Tip
这里分享一下如何使用 Maven 实现环境隔离。
在实际的项目开发中,会有许多的环境,如:开发环境(Dev)、测试环境(Beta)、生产环境(Prod)。这些环境之间会存在着配置的差异,如:FTP服务器相关配置不同、数据库配置不同… 使用 Maven 可以实现环境隔离。步骤:
- 在 pom.xml 中:
<build>
<resources>
<!-- 不同环境的资源文件 -->
<resource>
<directory>src/main/filters/${deploy.type}</directory>
</resource>
<!-- 所有公共资源文件 -->
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>
</build>
<profiles>
<profile>
<id>dev</id>
<activation>
<!--默认激活的是dev环境-->
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<deploy.type>dev</deploy.type>
</properties>
</profile>
<profile>
<id>beta</id>
<properties>
<deploy.type>beta</deploy.type>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<deploy.type>prod</deploy.type>
</properties>
</profile>
</profiles>
- 新建对应的文件夹,把要隔离的文件分开,公共的留下。
maven标准目录中,提供了一个filters目录用于存放资源过滤文件。推荐在filters目录下创建,而不是resources目录,因为resources目录中的文件默认情况下是不会被过滤的,还需在resources节点下额外的配置一些东西;这样的话结构也较清晰,resource目录存放公共资源文件,filters目录存放不同环境差异化资源文件。
- 在IDEA右侧Maven Products,选中本地开发环境对应的环境
- 打包命令:在Maven命令后加入参数
-P${环境标识}
,如:mvn clean package -Dmaven.test.skip=true -Pbeta
Share
Desperate times call for desperate measures.