阿里巴巴Java笔试题很难_2016阿里巴巴java笔试题

题目:

一个整形数组里除了一个数字出现3次以外,其他数字都出现2次.请写程序找出这个出现3次的数字.

要求使用辅助空间O1,时间复杂度Onlogn.

1.使用堆排序.(堆排序的时间复杂度为Onlogn)

因为堆排序每次取到的都是最大(或是最小)的数字,三个相同的数字肯定是紧挨着被取出的.

所以在原先的堆排序算法上,加2个标记记录即可.

代码:

// 使用堆排序,每次取最大的,连续取到3个相同的,那说明就是

public static int find2(int[] array) {

// 堆排序的:形成堆结构,

// 从最后一个有叶子节点的节点开始,

// 也就是最后一个节点的父节点

for (int i = (array.length >> 1) - 1; i >= 0; i--) {

refactor(array, i, array.length);

}

// 2个分别用来记录前以及前前

Integer pre = null;

Integer prePre = null;

for (int i = 1; i <= array.length; i++) {

// 如果相同,返回

if (pre != null && pre == prePre && array[0] == pre) {

return array[0];

}

if (pre == null) {

pre = array[0];

swap(array, 0, array.length - i);

refactor(array, 0, array.length - i);

continue;

}

prePre = pre;

pre = array[0];

swap(array, 0, array.length - i);

refactor(array, 0, array.length - i);

}

// 如果没找到,说明输入数组有问题,抛异常

throw new RuntimeException();

}

static void refactor(int[] array, int root, int length) {

int left = (root << 1) + 1;

int right = (root + 1) << 1;

if (left == length - 1 && array[left] > array[root]) {

swap(array, root, left);

return;

}

if (right < length) {

if (array[left] >= array[right] && array[left] > array[root]) {

swap(array, root, left);

refactor(array, left, length);

return;

}

if (array[right] > array[left] && array[right] > array[root]) {

swap(array, root, right);

refactor(array, right, length);

return;

}

}

}

private static void swap(int[] array, int a, int b) {

int tmp = array[a];

array[a] = array[b];

array[b] = tmp;

}

2.这里有个非常简单的方法:

那就是异或:

一个数异或他本身得到0,那么把所有的数异或得到的最后的结果肯定就是出现3次的那个数了.

public static int find1(int[] array) {

int target = array[0];

// 遍历,异或所有

for (int i = 1; i < array.length; i++) {

target ^= array[i];

}

// 最后的值就是本身

return target;

}

升级版:

剑指offer面试题40-数组中只出现一次的数字

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值