315. Count of Smaller Numbers After Self

315. Count of Smaller Numbers After Self#

开篇闲话:
两天没有刷题,前天白天复习了一遍jvm,晚上跟女朋友出去吃晚饭,回来就没心思敲代码,所以想干脆整理一下背包问题,博客链接—动态规划–背包问题
昨天晚上,实习公司因为为期六个月的实习项目终于完美落幕了,所以三个小组共同去撸串吃猪腰子了(听说是大补,哈哈哈),虽然直到离开,我也不清楚哪串肉,但玩的很开心,特别是中间,组长突然叫住我,跟我说,项目答辩的时候,我原来那个小组的组长(黄**组长)还夸我技术不错,基础扎实,你要好好保持学习下去,深入理解那些架构,哇,突然被夸,有点小激动,说不出的喜悦,赶紧回答,会的会的(哈哈哈,遗憾的是,可能太开心,竟然忘记向组长敬杯酒了)。感谢小组六个月的照顾,第一份实习,大家相处都很开心、融洽。

1. 题目描述
题目链接

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:
Input: [5,2,6,1]
Output: [2,1,1,0]
Explanation:
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.

2. 题目分析
因为一开始没有想法,动态规划不行,感觉不管怎样,每次都需要遍历一遍当前数值右边的所有数,才能找到比它小的数字,所以直接上暴力破解,但提交后发现超时,哈哈哈,心疼的抱着傻乎乎的自己。

3. 解决思路
参见网上的想法,原来可以从右边开始遍历,同时不断把已经遍历过的数字放到另外一个sort数组中,并且对这个sort数组进行升序存储,所以,如果要找当前数值右边有几个比它小的个数,那么就是要找到当前数值应该放入到sort数组中的位置(为了提高效率,使用二分查找法来确定当前数值应该放入的位置),即是它右边有几个比它小的个数。
example:
nums: [5,2,6,1]
当i = 3,nums[i] =1,sort[0]=nums[i];
当i = 2,nums[i] =6,通过在sort(目前只有元素1)中使用二分法查找,发现6应该插入到1后面,即index=1,sort[index]=nums[i];所以当前值6右边比它小的数字的个数为index=1

0123
16

当i = 1,nums[i] =2,通过在sort(目前只有元素1,6)中使用二分法查找,发现2应该插入到1后面,即index=1,sort[index]=nums[i];所以当前值2右边比它小的数字的个数为index=1

0123
126

当i = 0,nums[i] =5,通过在sort(目前只有元素1,6,2)中使用二分法查找,发现5应该插入到2后面,即index=2,sort[index]=nums[i];所以当前值5右边比它小的数字的个数为index=2

0123
1256

则,结果为Output: [2,1,1,0]

4. 代码实现(java)

package com.algorithm.leetcode.greedy;

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

/**
 * Created by 凌 on 2018/12/22.
 * 描述:315. Count of Smaller Numbers After Self
 */
public class CountSmaller {
    public static void main(String[] args) {
        int[] nums = {5,2,6,1};
        List<Integer> result = countSmaller(nums);
        for(Integer value : result){
            System.out.printf(value + "\t");
        }
    }
    public static List<Integer> countSmaller(int[] nums) {
        if(nums == null){
            return new ArrayList<Integer>();
        }
        Integer[] result = new Integer[nums.length];
        //对已经遍历的右边的数值进行升序存储,找到当前数值应该放入的位置,即是它右边有几个比它小的个数
        List<Integer> sort = new ArrayList<Integer>(nums.length);
        int left,right;
        int mid;
        for(int i=nums.length - 1;i >= 0;i--){
            left = 0;
            right = sort.size();
            //二分法查到当前数值的排序位置,即当前数值的右边有几个比它小的个数
            while (left < right){
                mid = left + (right - left)/2;
                if (sort.get(mid) >= nums[i]){
                    right = mid;
                }else{
                    left = mid + 1;
                }
            }
            result[i] = left;
            sort.add(left, nums[i]);
        }
        return Arrays.asList(result);
    }

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值