一)题目介绍
刚一开始看到这个题目的时候,下意识的想了一下,感觉很简单,认为只需要把这一串数字中最小的数去除掉就可以了。而这正是该题目中的一个陷阱,也是思考中的一个思维盲区。
比如说,当提供了一串如下图片数字的时候,那我们想的就是正确的了,直接把2去除就可以了。
但如果没有提供这一串数字的时候,那么上面这张图中的一串数字就只是题目中的某一种场景了。
二)题目分析
根据题目中的含义,如果没有给出具体的一串数字,分析之后,大概有5种场景。
场景一:
场景二:
场景三:
场景四:
场景五:
三)题目源码
题目场景分析之后的源码(代码中注释比较全面,从场景一分析到场景五):
/**
* 查找需要去除的数
* @param arr
* @return
*/
public static int findRemoveNumber(int[] arr) {
if (arr == null || arr.length == 0) {
throw new NullPointerException();
}
// 如果只有一个数,不需要比较,直接去除
if (arr.length == 1) {
return arr[0];
}
// 统计源数据中负数的个数
int negativeCount = 0;
for (int num : arr) {
if (num < 0) {
negativeCount++;
}
}
int tempIndex = 0; // 临时变量,记录需要去除数的下标
// 判断负数的个数是奇是偶,(negativeCount&1)==0表示负数有偶数个,(negativeCount&1)==1表示负数有奇数个,非偶就奇
if ((negativeCount&1) == 1) { // 奇个负数
// 全是负数
if (negativeCount == arr.length) {
// 场景一: 奇个负数,全是负数的情况,去掉了一个负数,就变成了偶数个负数了,所以需去掉绝对值最小的数(因为负负得正,偶数个负数相乘一定是正数)
for (int i = 1; i < arr.length; i++) {
if (Math.abs(arr[i]) < Math.abs(arr[tempIndex])) {
tempIndex = i;
}
}
} else {
// 场景二: 奇个负数,有负有正的情况,去掉了一个负数,就变成了偶数个负数了,所以需去掉绝对值最小的数(因为负负得正,偶数个负数相乘一定是正数),需考虑有0的情况
for (int i = 0; i < arr.length; i++) {
// 只有包含了0,就需直接去除
if (arr[i] == 0) {
tempIndex = i;
break;
} else {
// 只需要考虑负数的比较
if (arr[i] < 0) {
if (arr[tempIndex] < 0) {
if(Math.abs(arr[i]) < Math.abs(arr[tempIndex])) {
tempIndex = i;
}
} else {
tempIndex = i;
}
}
}
}
}
} else { // 偶个负数
// 全是负数
if (negativeCount == arr.length) {
// 场景三: 偶个负数,全是负数的情况,去掉了一个负数,就变成了奇数个负数了,所以需去掉绝对值最大的数(因为奇数个负数相乘一定是负数)
for (int i = 1; i < arr.length; i++) {
if(Math.abs(arr[i]) > Math.abs(arr[tempIndex])) {
tempIndex = i;
}
}
} else {
// 场景四: 偶个负数,有负有正的情况,需考虑0的情况,去掉了一个负数,就变成了奇数个负数了,所以需去掉绝对值最大的数(因为奇数个负数相乘一定是负数)
if (negativeCount > 0) {
for (int i=0; i<arr.length; i++) {
// 只有包含了0,就需直接去除
if (arr[i] == 0) {
tempIndex = i;
break;
} else {
// 只需要考虑负数的比较
if (arr[i] < 0) {
if (arr[tempIndex]<0) {
if(Math.abs(arr[i]) > Math.abs(arr[tempIndex])) {
tempIndex = i;
}
} else {
tempIndex = i;
}
}
}
}
} else {
// 场景五: 偶个负数(0个负数), 全部为正的情况,去掉最小的数
for (int i = 1; i < arr.length; i++) {
if (arr[i] < arr[tempIndex]) {
tempIndex = i;
}
}
}
}
}
// 返回源数据中需要去除的数
return arr[tempIndex];
}
测试源码:
public static void main(String[] args) {
// 判断一串数字中负数的奇偶个数
// 有奇个负数
// 全是负数
// 场景一: 奇个负数,全是负数的情况,去掉了一个负数,就变成了偶数个负数了,所以需去掉绝对值最小的数(因为负负得正,偶数个负数相乘一定是正数)
int[] arr1 = {-6, -9, -34, -5, -22, -10, -12};
System.out.println("场景一: 奇个负数,全是负数, 需去除的数为: " + findRemoveNumber(arr1));
// 有负有正,需考虑有0的情况
// 场景二: 奇个负数,有负有正的情况,去掉了一个负数,就变成了偶数个负数了,所以需去掉绝对值最小的数(因为负负得正,偶数个负数相乘一定是正数),需考虑有0的情况
int[] arr2 = {6, 12, 5, -9, 34, -22, -10};
System.out.println("场景二: 奇个负数,有负有正, 需去除的数为: " + findRemoveNumber(arr2));
// 有偶个负数
// 全是负数
// 场景三: 偶个负数,全是负数的情况,去掉了一个负数,就变成了奇数个负数了,所以需去掉绝对值最大的数(因为奇数个负数相乘一定是负数)
int[] arr3 = {-6, -5, -9, -34, -22, -10};
System.out.println("场景三: 偶个负数,全是负数, 需去除的数为: " + findRemoveNumber(arr3));
// 有负有正,需考虑有0的情况
// 场景四: 偶个负数,有负有正的情况,需考虑0的情况,去掉了一个负数,就变成了奇数个负数了,所以需去掉绝对值最大的数(因为奇数个负数相乘一定是负数)
int[] arr4 = {6, 5, -9, 34, -22, 10};
System.out.println("场景四: 偶个负数,有负有正, 需去除的数为: " + findRemoveNumber(arr4));
// 全部为正
// 场景五: 偶个负数(0个负数), 全部为正的情况,去掉最小的数
int[] arr5 = {6, 5, 9, 34, 2, 22, 10};
System.out.println("场景五: 偶个负数(0个负数), 全部为正, 需去除的数为: " + findRemoveNumber(arr5));
}
识别二维码关注个人微信公众号
本章完结,待续,欢迎转载!
本文说明:该文章属于原创,如需转载,请标明文章转载来源!