Java实现离散化

离散化

去重排序离散化 通过二分查找

public class SetAndMid {
​
    static int[] new_nums;
    // 去重以及下标映射
    public static void solve(int[] nums){
        Map<Integer,Integer> map = new TreeMap<>();
        for(var num:nums) map.put(num,1);
        int size = map.size();
        new_nums = new int[size];
        int cnt = 0;
        for(int key:map.keySet()) new_nums[cnt ++] = key;
​
    }
    
    // 二分查找对应的 x 的映射下标
    public static int find(int x){
        return Arrays.binarySearch(new_nums,x);
    }
​
    public static void main(String[] args) {
        int[] nums = new int[]{1,100,200,300,400,400,400,1000};
        solve(nums);
        for(int i = 0;i<new_nums.length;i++) System.out.println(i + " " + new_nums[i]);
​
        System.out.println(find(400));
    }
}

练习题目:树状数组加离散化

3072. 将元素分配到两个数组中 II - 力扣(LeetCode)

解题代码:

// 树状数组类
class Fenwick{
    int[] tree;

    Fenwick(int n) {
        tree = new int[n];
    }

    int lowbit(int x){
        return x & -x;
    }
    void add(int x,int u){
        for(int i = x;i< tree.length;i += lowbit(i)) tree[i] += u;
    }
    int query(int x){
        int ans = 0;
        for(int i = x;i > 0;i -= lowbit(i)) ans += tree[i];
        return ans;
    }
}


class Solution {
    public int[] resultArray(int[] nums) {
        int[] sorted = nums.clone();
        Arrays.sort(sorted);
        int n = nums.length;

        List<Integer> l1 = new ArrayList<>(n);
        List<Integer> l2 = new ArrayList<>();
        l1.add(nums[0]); l2.add(nums[1]);
        // System.out.print(nums[0] + " " + nums[1]);
        Fenwick t1 = new Fenwick(n + 1);
        Fenwick t2 = new Fenwick(n + 1);
        // 将初始元素添加到树状数组
        t1.add(Arrays.binarySearch(sorted,nums[0]) + 1, 1);
        t2.add(Arrays.binarySearch(sorted,nums[1]) + 1, 1);
        
        for(int i = 2;i<n;i++){
            int x = nums[i];
            int idx = Arrays.binarySearch(sorted,x) + 1;
            int a = l1.size() - t1.query(idx);
            int b = l2.size() - t2.query(idx);
            if(a > b || (a == b && l1.size() <= l2.size())) {
                l1.add(x);
                t1.add(idx, 1);
            }else {
                l2.add(x);
                t2.add(idx, 1);
            }
        }
        // for(int num:l1) System.out.print(num + " ");
        // for(int num:l2) System.out.print(num + " ");
        l1.addAll(l2);
        int[] ans = new int[n];
        int cnt = 0;
        for(int num:l1) ans[cnt ++] = num; 

        return ans;
    }
}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值