数组问题(解决元素出现次数)

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

思路分析:

方法一:先把数组进行排序,在有序数组中次数超过一半一定是中位数

             (该方法的时间复杂度取决于排序算法的时间复杂度)

方法二:通过HashMap中的key记录元素的值,value为元素的次数

              最后再遍历Hash,找到出现次数超过一半的数字

代码实现:

public static int moreThanHalfNum(int[] array) {
       if (array == null){
           return 0;
       }
       Map<Integer,Integer> res = new HashMap<>();
       for (int i =0;i< array.length;i++){
           //这个方法返回指定键所映射的值;如果此映射不包含该键的映射,则返回defaultValue(这里是0)
           res.put(array[i],res.getOrDefault(array[i],0)+1);
           if (res.get(array[i]) > array.length/2){
               return array[i];
           }
       }
       return 0;
    }

数组中只出现一次的数字

leetcode136

题目要求:给出一个数组,除了某个元素只出现一次以外,其余每个元素均出现两次,找出那个只出现一次的元素

思路分析:

方法一:可以利用Set集合不存重复值的特点

             也可以利用其他元素出现两次的特点,当遍历过程中发现遍历到的元素在集合中已经存在,不再进行添加操作,而是将集合中的key一起删除,最后剩下的就只有出现一次的数字

方法二:利用位运算中的异或运算

 异或运算的规则

由于数组中只有一个数字只出现一次,所以只要利用一个变量,通过n次异或最后剩下的就是只出现一次的数字

代码实现:

//添加到HashSet集合中去
 public int singleNumber(int[] nums) {

        Set<Integer> set = new HashSet<>();
        for(int i =0;i<nums.length;i++){
            if(! set.add(nums[i])){
                set.remove(nums[i]);
            }
        }
        return set.toArray(new Integer[set.size()])[0];
    }
//异或运算
public int singleNumber(int[] nums) {
    int flag = 0;
    for(int i =0;i<nums.length;i++){
          flag ^= nums[i]; 
     }
      return flag;
    }

颜色分类问题

leetcode75

题目要求:给定一个包含红色、白色和蓝色(用0、1、2表示),对它们进行排序,使得相同颜色相邻并按照红色、白色、蓝色顺序排序

思路分析:

方法一:基于冒泡排序的双指针(简单)

总共三个数字,所以只需要两次遍历,在第一次遍历中将所有0交换到数组的前面

                                                             第二次遍历将所有1交换到2的前面

方法二(一次遍历):

方法一是通过slow指针的移动,使得第一次遍历让所有0在slow指针的左边

基于这个思路,我们可以尝试三个指针

left指针: 让left的左侧元素全是0

right指针:让right的右侧元素全是2

index指针用于遍历整个链表,当index == right时说明遍历完成

代码实现:

 //三指针一次遍历
public void sortColors(int[] nums) {
        int left = 0;
        int right = nums.length-1;
        int index= 0;

        for(;index <= right;){

            //如果是2 index指针先不移动(可能调转回来的仍是2)
            if(nums[index] == 2){
                int temp = nums[right];
                nums[right--] = nums[index];
                nums[index] = temp;
            }
            //如果是0的情况直接放最前面 index也要随着变化
            else if(nums[index] == 0){
                int temp = nums[left];
                nums[left++] = nums[index];
                nums[index++] = temp;
            }
            //指针指向1的情况,最终结果是index的左边全是1
            else {
                index++;
            }
        }
    }

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值