算法通关村第三关 | 数组黄金挑战

文章介绍了三种数组处理算法:1)使用HashMap统计出现次数找出数组中超过一半的数字;2)遍历数组,通过计数找到多数元素;3)解决荷兰国旗问题,即颜色分类,通过双指针策略进行排序。
摘要由CSDN通过智能技术生成

1. 数组中出现超过一半的数字

第一种:用Hash,我们先创建一个HashMap的key是元素的值,value是已经出现的次数,然后遍历数组来统计所有元素的出现次数,同时遍历哈希判断value是否超过一半的数字,

第二种:可以在遍历数组的时候设置两个初始值:一个是数组中的数result,另一个是出现的次数times,和第一种的思想有一点点联系,result初始值设为null,times设为0;

遍历数组,初始的时候,result=第一个元素,times=1,

当出现与result元素相同的元素,times+1;否认则times-1;

当times=0的时候,result等于下个位置元素,

例子:[1,2,1,3,1,4,1]和[2,1,2,3,1,4,1]两个序列

第一个:

1. result = 1, times = 1,

2.result !=2,times = 0,下一轮改变result = 1

3. result =1 times = 1,

4,result != 3 ,times= 0;下一轮改变result=1

5.result = 1 times = 1,

6.result !=4 times = 0, 下一轮,

7.result = 1,times = 1

返回最后result的值,第二种最后result仍然是1,大家可以自己尝试,

如过result在数组中出现超过一半,则随后times >=1 ,正好一半的时候,times=0,例如[1,2,1,3,1,4]最后结果是0,所以最后还是要检查一下,

代码:

    public static int majorityRlement(int[] nums){
        //count表示出现次数,result初始设置为null遍历到第一个元素,赋值
        int count = 0;
        Integer result = null;
        for (int a:nums
             ) {
            if (count == 0){
                result = a;
            }
            count += (result == a)?1:-1;
        }
        return result;
    }

2.题目中只出现一次的数字

题目:LeetCode136,

 位运算也就是异或运算

0和其他数字异或还是那个数字,0和0异或还是0,因为只有一个元素出现一次所以异或最合适

    public static int find(int[] arr){
        int flag = 0;
        for (int a:arr
             ) {
            flag ^=a;
        }
        return flag;
    }

3.颜色分类问题(荷兰国旗问题)

 第一种方法:我们使用两次遍历,第一次遍历将数字0交换到左边,第二次遍历将数字1交换到数字2的前面

第二种方法:

left指针表示所有左侧元素都是0;

right表示右侧元素都是2

index,从头到尾遍历数组,根据nums[index]是0还是2决定与左还是右交换

当index位置是1的时候,我们不需要交换,直接index++,后面出现0的话会被交互到左边,

index=right时候停止,index=2的时候right-- index不变,因为被交换到右边的是2,被交换到左边的不能确定,需要重新判断是0还是1再做交换,而index=0的时候被交换到左边的一定是0,left++无疑问,而index++如果index左边存在2会被交换到右边,

 代码实现

    public void colorswap(int[] nums){
        int left = 0;int right = nums.length-1;
        int index = 0;
        while (index <=right){
            if (index == 0){
                swap(nums,index++,left++);
            }else if (index == 2){
                swap(nums,index,right--);
            }else {
                index++;
            }
        }
    }
    public void swap(int[] nums,int i,int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值