LeetCode刷题记161-315. 计算右侧小于当前元素的个数【再做一遍】

3 篇文章 0 订阅
3 篇文章 0 订阅

LeetCode刷题记161

315. 计算右侧小于当前元素的个数

题目
在这里插入图片描述

class Solution {
    public List<Integer> countSmaller(int[] nums) {        
        // discretize离散化数字
        Set<Integer> set = new HashSet<Integer>();
        for (int num : nums) {
            set.add(num);
        }
        int[] tmp = new int[set.size()];
        int id = 0;
        for (int num : set) {
            tmp[id ++] = num;
        }
        Arrays.sort(tmp);
        // TreeMap<Integer, Integer> map = new TreeMap<Integer, Integer>();
        // id = 0;
        // for (int num : set) {
        //     map.put(num, id ++);
        // }

        int[] tree_array = new int[nums.length + 5];  // 记录树状数组
        List<Integer> ans = new ArrayList<Integer>(); 
        for (int i = nums.length - 1; i >= 0; --i) {
            // int pos = map.get(nums[i]);
            int pos = Arrays.binarySearch(tmp, nums[i]);
            ans.add(query(pos, tree_array));
            update(pos + 1, 1, tree_array);
        }
        Collections.reverse(ans);
        return ans;
    }

    private int lowBit(int x) {
        return x & (-x);
    }

    private void update(int pos, int num, int[] c) {
        while (pos < c.length) { 
            c[pos] += num;
            pos += lowBit(pos);
        }
    }

    private int query(int pos, int[] c) {
        int ret = 0;
        while (pos > 0) {
            ret += c[pos];
            pos -= lowBit(pos);
        }
        return ret;
    }
}

经典的树状数组的题目,但是我忘记树状数组怎么写的了,还是看了答案。。。
树状数组原理不讲了,网上很多,而且我讲不清楚。主要说一下怎么记忆update和query函数,哈哈哈。

update函数是更新数组的,那么对应位置就要加num;
update是up,位置更新对应“+”,那么循环就要小于上限->数组长度。

private void update(int pos, int num, int[] c) {
   while (pos < c.length) { 
        c[pos] += num;
        pos += lowBit(pos);
    }
}

query是查询,那么返回结果的数据要加上对应位置的数字;
位置更新是要加上当前位置之前的数字,所以是“-”,那么循环就要大于下限->0。

private int query(int pos, int[] c) {
    int ret = 0;
    while (pos > 0) {
        ret += c[pos];
        pos -= lowBit(pos);
    }
    return ret;
}

小知识点:
public static int binarySearch(Object[] a, Object key)
通过二分法在已经排好序的数组中查找指定的元素,并返回该元素的下标;
如果数组中不存在该元素,则会返回 -(插入点 + 1)。

int[] a = {10, 20, 30, 40};
System.out.println(Arrays.binarySearch(a, 20)); //1
System.out.println(Arrays.binarySearch(a, 25)); //-3,插入点在20和30之间,就是2的位置
System.out.println(Arrays.binarySearch(a, 35)); //-4

用归并排序的方法再做一遍

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值