315. Count of Smaller Numbers After Self && 493. Reverse Pairs

You are given an integer array nums and you have to return a new counts array. The counts array has the property where counts[i] is the number of smaller elements to the right of nums[i].

Example:

Given nums = [5, 2, 6, 1]

To the right of 5 there are 2 smaller elements (2 and 1).
To the right of 2 there is only 1 smaller element (1).
To the right of 6 there is 1 smaller element (1).
To the right of 1 there is 0 smaller element.

Return the array [2, 1, 1, 0].



思路:MergeSort,但是要记录数据在变化过程中的index变化,即最开始在哪要维持

import java.util.ArrayList;
import java.util.List;

public class Solution {
	
	// indexMap: 现在的index对应原来的indexMap[index]
	int[] indexMap, dumpIndexMap, smaller;
	
    public List<Integer> countSmaller(int[] nums) {
        indexMap = new int[nums.length];
        for(int i=0; i<nums.length; i++)	indexMap[i] = i;
        dumpIndexMap = new int[nums.length];
        smaller = new int[nums.length];
        
        sort(nums, new int[nums.length], 0, nums.length-1);
        
        List<Integer> rst = new ArrayList<Integer>();
        for(int i : smaller)	rst.add(i);
    	return rst;
    }
    
    
    public void sort(int[] a, int[] aux, int lo, int hi) {
    	if(hi <= lo)	return;
    	int mid = lo + (hi - lo) / 2;
    	sort(a, aux, lo, mid);
    	sort(a, aux, mid+1, hi);
    	merge(a, aux, lo, mid, hi);
    }


	private void merge(int[] a, int[] aux, int lo, int mid, int hi) {
		
		// 原始数组需要保存一份,indexMap也需要保存一份
		// 否则赋值给indexMap[k]就可能不正确
		for(int k=lo; k<=hi; k++) {
			aux[k] = a[k];
			dumpIndexMap[k] = indexMap[k];
		}
		
		int i = lo, j = mid+1;
		for(int k=lo; k<=hi; k++) {
			if(i > mid) {
				a[k] = aux[j++];
				indexMap[k] = dumpIndexMap[j-1];
			} else if(j > hi) {
				a[k] = aux[i++];
				indexMap[k] = dumpIndexMap[i-1];
				smaller[indexMap[k]] += j-mid-1;
			} else if(aux[j] < aux[i])	{
				a[k] = aux[j++];
				indexMap[k] = dumpIndexMap[j-1];
			} else	{
				a[k] = aux[i++];
				indexMap[k] = dumpIndexMap[i-1];
				smaller[indexMap[k]] += j-mid-1;
			}
		}
	}
}




Given an array nums, we call (i, j) an important reverse pair if i < j and nums[i] > 2*nums[j].

You need to return the number of important reverse pairs in the given array.

Example1:

Input: [1,3,2,3,1]
Output: 2

Example2:

Input: [2,4,3,5,1]
Output: 3

Note:

  1. The length of the given array will not exceed 50,000.
  2. All the numbers in the input array are in the range of 32-bit integer.

思路:上一题的变行,注意数据溢出的问题

public class Solution {
	
	int ret = 0;
	
    public int reversePairs(int[] nums) {
    	if(nums.length == 0)	return 0;
        sort(nums, new int[nums.length], 0, nums.length-1);
        return ret;
    }

	public void sort(int[] a, int[] aux, int s, int t) {
		if(s == t)	return;
		
		int mid = (s + t) / 2;
		sort(a, aux, s, mid);
		sort(a, aux, mid+1, t);
		merge(a, aux, s, mid, t);
	}

	private void merge(int[] a, int[] aux, int s, int mid, int t) {
		for(int i=s; i<=t; i++)	aux[i] = a[i];
		
		// BS find the last position smaller than a[s..mid]/2
		for(int i=s; i<=mid; i++) {
			int p = bs(a, mid+1, t, a[i]>0 && a[i]%2==1 ? a[i]/2 : a[i]/2-1);
			ret += p - mid;
		}
		
		int p = s, q = mid+1;
		for(int i=s; i<=t; i++) {
			if(p > mid)				a[i] = aux[q++];
			else if(q > t)			a[i] = aux[p++];
			else if(aux[q]<aux[p])	a[i] = aux[q++];
			else					a[i] = aux[p++];
		}
	}

	public int bs(int[] a, int lo, int hi, int t) {
		if(a[lo] > t)	return lo-1;
		while(lo+1 < hi) {
			int mid = (lo + hi) / 2;
			if(a[mid] > t)	hi = mid - 1;
			else			lo = mid;
		}
		return a[hi] <= t ? hi : lo;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值