首页 > 其他分享 >Leetcode 315. 计算右侧小于当前元素的个数

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

时间:2024-09-18 10:46:32浏览次数:1  
标签:index 遍历 nums self 个数 315 数组 Leetcode

1.题目基本信息

1.1.题目描述

给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

1.2.题目地址

https://leetcode.cn/problems/count-of-smaller-numbers-after-self/description

2.解题方法

2.1.解题思路

离散化+树状数组求前缀和

2.2.解题步骤

第一步,离散化。比如-1,2,6,6,8->0,1,2,2,3。首先将numsSet集合进行升序排序数组,然后遍历该数组,获取nums中每个数字的离散数值的映射map。然后遍历nums,将每个数字替换成离散值。

第二步,逆向遍历nums,并获取当前的nums[i]前面遍历的比nums[i]小的个数(即nums中索引比i大的且数值比nums[i]小的个数)。为了获取这个个数,这里可以用到树状数组,假设树状数组的原数组为a,则a[j]表示nums中已经遍历的各个数值b中,b==j的个数,则a数组的前缀和T[j-1]即为nums中已经遍历的数值中比j小的数值的个数,即为当前的result[i]的值。

3.解题代码

Python代码

# ==> 树状数组
class TreeArr():
    def __init__(self,length):
        self.length=length
        self.init()
    
    # 初始化树状数组
    def init(self):
        self.arr=[0]*self.length
    
    # 二进制从右向左第一个1和其右边的0组成的数字
    def lowerbit(self,x):
        return x&(-x)   # 计算机的负数采用的是补码(和取反加1效果一致)
    
    # 原数组a[index]增加val,更新树状数组
    def add(self,index,val):
        while index<self.length:
            self.arr[index]+=val
            index=index+self.lowerbit(index+1)
    
    # a[0]->a[index]项前缀和
    def query(self,index):
        sum_=0
        while index>=0:
            sum_+=self.arr[index]
            index-=self.lowerbit(index+1)
        return sum_

class Solution:
    def countSmaller(self, nums: List[int]) -> List[int]:
        length=len(nums)
        numsSet=set(nums)
        tree=TreeArr(len(numsSet))
        # 第一步,离散化。比如-1,2,6,6,8->0,1,2,2,3。首先将numsSet集合进行升序排序数组,然后遍历该数组,获取nums中每个数字的离散数值的映射map。然后遍历nums,将每个数字替换成离散值。
        discreteMap={}  # 离散值从0开始
        for i,num in enumerate(sorted(numsSet)):
            discreteMap[num]=i
        for i in range(length):
            nums[i]=discreteMap[nums[i]]
        # print(nums)
        # 第二步,逆向遍历nums,并获取当前的nums[i]前面遍历的比nums[i]小的个数(即nums中索引比i大的且数值比nums[i]小的个数)。为了获取这个个数,这里可以用到树状数组,假设树状数组的原数组为a,则a[j]表示nums中已经遍历的各个数值b中,b==j的个数,则a数组的前缀和T[j-1]即为nums中已经遍历的数值中比j小的数值的个数,即为当前的result[i]的值。
        result=[0]*length
        for i in range(length-1,-1,-1):
            result[i]=tree.query(nums[i]-1)
            tree.add(nums[i],1)
        return result

4.执行结果

在这里插入图片描述

标签:index,遍历,nums,self,个数,315,数组,Leetcode
From: https://www.cnblogs.com/geek0070/p/18418075

相关文章

  • 代码随想录Day3 | LeetCode 203. 移除链表元素、LeetCode 707. 设计链表、LeetCode 20
    LeetCode203.移除链表元素链表基础概念题,也可以用递归做,不过我们把递归的思想放在更能体现它的LeetCode206.反转链表#Definitionforsingly-linkedlist.#classListNode:#def__init__(self,val=0,next=None):#self.val=val#self.next......
  • 代码随想录Day4 | LeetCode 24. 两两交换链表中的节点、LeetCode 19. 删除链表的倒数
    LeetCode24.两两交换链表中的节点递归思想#Definitionforsingly-linkedlist.#classListNode:#def__init__(self,val=0,next=None):#self.val=val#self.next=nextclassSolution:defswapPairs(self,head:Optional[ListNode......
  • LeetCode415周赛T2 +T3
    最高乘法得分动态规划解决从数组b中选择下标的问题题目描述给你一个大小为4的整数数组a和一个大小至少为4的整数数组b。你需要从数组b中选择四个下标i0,i1,i2,和i3,并且要求满足i0<i1<i2<i3。你的得分将是:a[0]*b[i0]+a[1]*b[i1]+a[2]*b......
  • leetcode232. 用栈实现队列
    leetcode232.用栈实现队列请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):实现MyQueue类:voidpush(intx)将元素x推到队列的末尾intpop()从队列的开头移除并返回元素intpeek()返回队列开头的元素booleanempt......
  • 一个线性筛的多功能组合:筛法求质数+约数个数+约数和
    F:\BC\2024\9>main1活动代码页:9362 2X2=43 3X2=6 3X3=94X2=85 5X2=10 5X3=15 5X5=256X2=127 7X2=14 7X3=21 7X5=35 7X7=498X2=169X2=18 9X3=2710X2=2011 11X2=22 11X3=33 11X5=55 11X7=77 11X11=12112X2=2413 13X2=26 13X......
  • 代码随想录Day2 | LeetCode 209. 长度最小的子数组、LeetCode 59. 螺旋矩阵 II、KamaC
    LeetCode209.长度最小的子数组子数组是一个连续的,很容易想到滑动窗口classSolution:defminSubArrayLen(self,target:int,nums:List[int])->int:windowSum=0left,right=0,0res=float('inf')whileright<len(nums......
  • 素数个数[中秋快乐~]
    题目描述编程求 2 ~ n (包括 n)中有多少个素数。输入格式输入 n(2≤n≤50000)。输出格式素数个数。输入数据110 输出数据14代码#include<bits/stdc++.h>usingnamespacestd;intmain(){intn,ans=0;cin>>n;for(inti=2;i<=n;i++){......
  • Day5||242.有效的字母异位词|349.两个数组的交集|202.快乐数|1.两数之和
    哈希表理论基础哈希表(hashtable):是根据关键码的值而直接进行范围的数据结构。如数组也是一张哈希表。 解决问题:一般哈希表都是用来快速判断一个元素是否出现集合里。(牺牲空间换取时间)例如要查询一个名字是否在这所学校里。要枚举的话时间复杂度是O(n),但如果使用哈希表......
  • 【LeetCode Hot 100】5. 最长回文子串
    题目描述考虑回文字符串的特点,从左往右和从右往左读都是一样的,就是说字符串成了“轴对称”。要求一字符串的最长回文子串,我们可以遍历每个字符,求以该字符为轴对称中心的最长对称子串(或者以该字符和下一个字符为中间两个字符的对称子串),在所有这样的子串中长度最长的那个就是我们要......
  • leetCode2:两数相加(链表)
    题目:给你两个非空的链表,表示两个非负的整数。它们每位数字都是按照逆序的方式存储的,并且每个节点只能存储一位数字。请你将两个数相加,并以相同形式返回一个表示和的链表。你可以假设除了数字0之外,这两个数都不会以0开头。思路:遍历两个链表,逐位相加,还要加上进位结......