《算法闯关第三关——黄金挑战》

系列文章目录

一、数组出现次数超过一般的数字

leetcode:给定一个大小为 n 的数组 nums ,返回其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。

你可以假设数组是非空的,并且给定的数组总是存在多数元素。

示例 1:
输入:nums = [3,2,3]
输出:3

使用hash表,记录元素出现的次数

代码如下

       HashMap<Integer, Integer> hashMap = new HashMap<>();
        for(int i=0;i<nums.length;i++){
            hashMap.put(nums[i],hashMap.getOrDefault(nums[i],0)+1);
            if(hashMap.get(nums[i])>nums.length/2){
                return nums[i];
            }
        }
        return -1;
    }

出现次数超过一般,则用该数的出现的次数一定大于其他数出现次数的总和

代码如下

   public int majorityElement(int[] nums) {
        int num=nums[0];
        int cishu=1;
        for(int i=1;i<nums.length;i++){
            if(nums[i]==num){
                cishu++;
            }else{
                cishu--;
            }
            if(cishu==0){
                num=nums[i];
                cishu++;
            }
        }
        return num;
}

二、只出现一次的数字

leetcode136:给你一个 非空 整数数组 nums ,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
你必须设计并实现线性时间复杂度的算法来解决此问题,且该算法只使用常量额外空间。

示例 1 :
输入:nums = [2,2,1]
输出:1

借助集合的特性,第一输入,第二次删除,仅剩余的元素就是我们需要的

代码如下

public int singleNumber(int[] nums) {
        Set<Integer> integers = new HashSet<>();
        for(int i=0;i<nums.length;i++){
            if(!integers.add(nums[i])){
                integers.remove(nums[i]);
            }
        }
      
       return (Integer) integers.toArray()[0];
    }

出现两次,也可以采用异或,将集合所有元素异或,最后剩余的就是我们想要的

 public int singleNumber(int[] nums) {
       int temp=nums[0];
        for(int i=1;i<nums.length;i++){
           temp=temp^nums[i];
        }
        return temp;
      
    }

三、荷兰国旗问题

leetcode:给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]

使用三个指针,一个指针值控制0,一个指针控制2,一个指针循环

代码如下

       public void sortColors(int[] nums) {
           int left=0,right=nums.length-1;
           int index=0;
           while(index<right){
               if(nums[index]==0){
                   swap(nums,index++,left++);
               }else if(nums[index]==2){
                   swap(nums,index,right--);
               }else{
                   index++;
               }
           }
    }
    public void swap(int []arr,int i,int j){
        int temp=arr[i];
        arr[i]=arr[j];
        arr[j]=temp;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值