数组与双指针

数组中出现次数超过一半的数字

使用hashMap

记录每个数字出现次数,寻找出现次数超过一半的数字。

    public static int moreThanHalfNum(int[] nums){
        if (nums == null){
            return 0;
        }
        Map<Integer,Integer> map= new HashMap<>();
        int len = nums.length;
        for (int i = 0; i< len;i++){
            map.put(nums[i],map.getOrDefault(nums[i],0)+1);
            if (map.get(nums[i])>len/2){
                return nums[i];
            }
        }
        return 0;
    }

拓展方法

令result = nums[0],times = 1;

如果nums[1]!=nums[0],times-1;

如果nums[1]==nums[0],times+1;

当times==0时,改变result,再令times=1;

重复以上步骤,若最后times>1,则result为出现次数超过一半的数字。

[1,2,1,1,3,1,4,1]

result=1,times=1;

1!=2;times-=1;times==0;result=2;times=1;

2!=1;times-=1;times==0;result=1;times=1;

1==1;times+=1;times==2;

3!=1times-=1;times==1;

1==1;times+=1;times==2;

4!=1;times-=1;times==1;

1==1;times+=1;times==2;

public static int moreThanHalf(int[] nums){
        int count = 0;
        Integer candidate = null;
        for (int num:nums){
            if (count==0){
                candidate = num;
            }
            System.out.println("candidate"+candidate);
            if (num!=candidate){
                count--;
            }else {
                count++;
            }
            if (count == 0){
                candidate = num;
                count = 1;
            }
            System.out.println("count"+count);
        }
        return count==1?0:candidate;
    }

数组中只出现一次的数字

除了某个元素只出现一次外,其余每个元素均出现两次,找出只出现一次的元素。

使用set集合

将元素加入set集合中,因重复加入时而失败时,删除要加入元素的对应元素,最后剩下的元素为出现了一次的元素。

    public static Integer findOneNum(int[] arr){
        Set<Integer> set = new HashSet<>();
        for (int i:arr){
            if (!set.add(i)){
                set.remove(i);
            }
        }
        if (set.size()==0){
            return null;
        }
        return set.toArray(new Integer[set.size()])[0];
    }

使用位运算

二进制位运算,异或结合律,相同为0,相异为1,两个相同的数异或后得0,0异或其它数仍为其它数。
    public static Integer findOneNum02(int[] arr){
        int flag = 0;
        for (int i:arr){
            flag^=i;
        }
        return flag;
    }

找出数组中的重复数字

    public static Set findDuplicates(int[] arr){
        Set<Integer> set = new HashSet<>();
        Set<Integer> res = new HashSet<>();
        for (int i : arr){
            if (!set.add(i)){
                res.add(i);
            }
        }
        return res;
    }
    //可以改变map.get(i)>?来找到出现相应次数的元素
    public static Set findDuplicates02(int[] arr){
        Map<Integer,Integer> map = new HashMap<>();
        Set set = new HashSet();
        for (int i:arr){
            map.put(i,map.getOrDefault(i,0)+1);
            if (map.get(i)>1){
                set.add(i);
            }
        }
        return set;
    }

leetcode137

别人的详细解法

    public static int singleNumber(int[] arr){
        int a = 0,b=0;
        for (int i = 0;i < arr.length;i++){
            b = (b^arr[i])&~a;
            a = (a^arr[i])&~b;
        }
        return b;
    }

颜色分类问题

leetcode75

0、1、2代表红、白、蓝三色,进行原地排序,按照红白蓝顺序排,相同颜色相邻。

双指针

找到nums[right]==0,与nums[left]进行交换,left++;

找到nums[right]==1,与nums[left]进行交换,left++.

    //2次遍历,O(2n)
    public static void colorClassify(int[] arr){
        int n = arr.length;
        int left = 0;
        int right = 0;
        for (;right<n;right++){
            if (arr[right]==0){
                int temp = arr[right];
                arr[right] = arr[left];
                arr[left] = temp;
                left++;
            }
        }

        for (right = left;right<n;right++){
            if(arr[right]==1){
                int temp = arr[right];
                arr[right]=arr[left];
                arr[left]=temp;
                left++;
            }
        }
    }

三指针

left左侧全为0

right右侧全为2

index进行遍历,将0和2与left和right进行交换。

    //一次遍历,O(n)
    public static void colorClassify02(int[] arr){
        int n = arr.length;
        int left = 0;
        int right = n - 1;
        int index = 0;
        for (;index<n;index++){
            if (index==right){
                break;
            }
            if (arr[index]==0){
                int temp = arr[index];
                arr[index]=arr[left];
                arr[left]=temp;
                left++;
            }else if (arr[index] == 2){
                int temp = arr[right];
                arr[right]=arr[index];
                arr[index]=temp;
                right--;
            }
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值