找出一批正整数中的最大偶数_#面试题--找出数组中的唯一值

这是一篇关于解决面试题的文章,主要探讨如何在一组正整数中找出仅出现一次的元素。文章提供了四种解法:排序后遍历、使用HashMap、位数组和异或运算,并对这些算法进行了性能比较。此外,还提到了使用Linux uniq命令来解决此问题的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#面试题 找出数组中的唯一值

数组中仅有一个元素出现了一次, 其他元素均出现了两次, 找出其中的唯一值,如数组: [3 4 5 2 3 4 5], 2只出现了一次,即要找出2.

解法1(sort):

/**

* 算法1

* 1. 先排序

* 2. 若a[i+1]!=a[i] (i为偶数)或a[i+1]不存在 则a[i]为唯一元素

*

* [3 4 5 2 3 4 5]

* [2 3 3 4 4 5 5]

* a[1]!=a[0] ==> a[0]为唯一元素

*

* [3 4 5 2 2 4 5]

* [2 2 3 4 4 5 5]

* a[3]!=a[2] ==> a[2]为唯一元素

* [3 4 5 2 2 4 3]

* [2 2 3 3 4 4 5]

* a[7]不存在 ==> a[6]为唯一元素

* @param a

*/

public static int findUniqueValue1(final int[] a){

int[] b = a.clone();

Arrays.sort(b);

int result = -1;

for (int i = 0; i 

if(i+1==b.length || b[i+1]!=b[i]){

result = b[i];

break;

}

}

return result;

}

解法2(map):

/**

* 算法2

* 利用 map

* 如果key(a[i])已存在 直接删除 若不存在 添加

* 最后剩下唯一的key即为所求的唯一元素

* @param a

*/

public static int findUniqueValue2(final int[] a){

Map map = new HashMap<>();

for (int i = 0; i 

if(map.containsKey(a[i]))

map.remove(a[i]); //off

else

map.put(a[i], null); //on

}

int result = -1;

for (Integer key : map.keySet())

result = key;

return result;

}

解法3(位数组):

/**

* 算法3

* 利用位数组 Bit[] bits

* 如果key(a[i])不存在 bits[a[i]]=1 若已存在 bits[a[i]]=0

* 最后bits数组中等于1的索引值即为所求值

* 如

* 数组 a: [3 4 5 2 3 4 5]

*

* init bit array: [0 0 0 0 0 0]

* [0 0 0 1 0 0]

* [0 0 0 1 1 0]

* [0 0 0 1 1 1]

* [0 0 1 1 1 1]

* [0 0 1 0 1 1]

* [0 0 1 0 0 1]

* [0 0 1 0 0 0]

* @param a

* @param max 数组中的最大值

*/

public static int findUniqueValue3(final int[] a, int max){

BitSet bitSet = new BitSet(max);

for (int i = 0; i 

bitSet.flip(a[i]);

}

int result = -1;

for (int i = 0; i <= max; i++) {

if(bitSet.get(i)){

result = i;

break;

}

}

return result;

}

解法4(异或):

/**

* 算法4

* 利用自己与自己异或为0的特点 如 3 ^ 3 = 0

* [3 4 5 2 3 4 5]

* 3^4^5^2^3^4^5=2

* @param a

*/

public static int findUniqueValue4(final int[] a){

int t=a[0] ;

for (int i = 1; i 

t ^= a[i];

return t;

}

下面是对上述四种算法的性能比较:

算法1(sort)

算法2(map)

算法3(bit array)

算法4(异或)

1

351

422

55

24

2

244

342

57

1

3

135

298

11

1

4

136

168

10

0

5

135

366

12

1

注: 数组大小为1,000,001, 一共运行了5次, 在循环内部分别调用上述4个方法,每个调用之间休眠1秒,运行时间单位是毫秒(ms)

解法5(linux uniq):

利用LInux命令, 如下所示:

$ cat uniq_test.txt

3

4

5

2

3

4

5

$ sort uniq_test.txt | uniq -u

2

同样测试在1,000,001行的文件中寻找唯一值时的花费,

$ cat find_uniq_value_test.txt | wc -l

1000001

$ time sort find_uniq_value_test.txt | uniq -u

1000001

real0m2.907s

user0m9.426s

sys0m0.039s

需要2秒多.

补充:

构造一个满足要求的测试文本的shell命令

$ seq 1 2 10

1

3

5

7

9

$ seq 1 2 10 > temp.txt

$ seq 1 2 10 >> temp.txt

$ echo 11 >> temp.txt

$ cat temp.txt

1

3

5

7

9

1

3

5

7

9

11

$ shuf temp.txt

7

3

5

11

1

1

5

9

7

9

3

$ shuf temp.txt > temp_shuf.txt

$ sort -n temp_shuf.txt | uniq -u

11

参考了:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值