Algorithm


Problem Name: 315. Count of Smaller Numbers After Self

Given an integer array nums, return an integer array counts where counts[i] is the number of smaller elements to the right of nums[i].

 

Example 1:

Input: nums = [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.

Example 2:

Input: nums = [-1]
Output: [0]

Example 3:

Input: nums = [-1,-1]
Output: [0,0]

 

Constraints:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

Code Examples

#1 Code Example with C Programming

Code - C Programming


typedef struct node_s {
    int key;
    int lnum;
    int dup;
    struct node_s *left;
    struct node_s *right;
} node_t;
void insert(node_t **nodep, node_t *buff, int key, int *pi, int lnum) {
    node_t *node = *nodep;
    if (!node) {
        *pi = lnum;
        node = buff;
        node->key = key;
        node->dup = 1;
        *nodep = node;
    } else if (node->key == key) {
        node->dup ++;
        *pi = lnum + node->lnum;
    } else if (node->key > key) {
        node->lnum ++;
        insert(&node->left, buff, key, pi, lnum);
    } else {
        insert(&node->right, buff, key, pi, lnum + node->lnum + node->dup);
    }
}
int* countSmaller(int* nums, int numsSize, int* returnSize) {
    int *p, i;
    node_t *node, *buff;
​
    p = malloc(numsSize * sizeof(int));
    buff = calloc(numsSize, sizeof(node_t));
    //assert(p && buff);
    
    node = NULL;
    for (i = numsSize - 1; i >= 0; i --) {
        insert(&node, &buff[i], nums[i], &p[i], 0);
    }
    
    free(buff);
    *returnSize = numsSize;
    
    return p;
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
nums = [5,2,6,1]

Output

x
+
cmd
[2,1,1,0]

#2 Code Example with C++ Programming

Code - C++ Programming


class Solution {
    struct TreeNode{
        int val;
        int sum;
        TreeNode* left;
        TreeNode* right;
        TreeNode(int x, int y): val(x), sum(y), left(NULL), right(NULL){}
    };
public:
    vector<int> countSmaller(vector<int>& nums) {
        TreeNode* root = NULL;
        vector<int>res(nums.size());
        for(int i = nums.size() - 1; i >= 0; i--) root = buildTree(root, i, nums[i], 0, res);
        return res;
    }
    
    TreeNode* buildTree(TreeNode* root, int i, int val, int count, vector<int>& res){
        if(!root){
            root = new TreeNode(val, 1);
            res[i] = count;
            return root;
        }
        if(val > root->val) root->right = buildTree(root->right, i, val, count + root->sum, res);
        else{
            root->sum++;
            root->left = buildTree(root->left, i, val, count, res);
        }
        return root;
    }
};
Copy The Code & Try With Live Editor

Input

x
+
cmd
nums = [5,2,6,1]

Output

x
+
cmd
[2,1,1,0]

#3 Code Example with Java Programming

Code - Java Programming


class Solution {
  public List countSmaller(int[] nums) {
    int n = nums.length;
    int[] result = new int[n];
    int[] indices = new int[n];
    for (int i = 0; i  <  n; i++) {
      indices[i] = i;
    }
    mergesort(indices, 0, n, result, nums);
    return Arrays.stream(result).boxed().collect(Collectors.toList());
  }
  
  private void mergesort(int[] indices, int left, int right, int[] result, int[] nums) {
    if (right - left  < = 1) {
      return;
    }
    int mid = (left + right) / 2;
    mergesort(indices, left, mid, result, nums);
    mergesort(indices, mid, right, result, nums);
    merge(indices, left, right, mid, result, nums);
  }
  
  private void merge(int[] indices, int left, int right, int mid, int[] result, int[] nums) {
    int i = left;
    int j = mid;
    List < Integer> temp = new ArrayList<>();
    while (i < mid && j < right) {
      if (nums[indices[i]] <= nums[indices[j]]) {
        result[indices[i]] += j - mid;
        temp.add(indices[i]);
        i++;
      } else {
        temp.add(indices[j]);
        j++;
      }
    }
    while (i  <  mid) {
      result[indices[i]] += j - mid;
      temp.add(indices[i]);
      i++;
    }
    while (j  <  right) {
      temp.add(indices[j]);
      j++;
    }
    for (int k = left; k  <  right; k++) {
      indices[k] = temp.get(k - left);
    }
  }
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
nums = [-1]

Output

x
+
cmd
[0]

#4 Code Example with Javascript Programming

Code - Javascript Programming


const countSmaller = function(nums) {
  const numsAndIndexes = nums.map((x, i) => [x, i])
  const output = [...new Array(nums.length)].map(_ => 0)
  mergeSort(numsAndIndexes, output)
  return output
}

function mergeSort(arr, output) {
  if (arr.length <= 1) return arr
  const middle = Math.floor(arr.length / 2)
  const left = mergeSort(arr.slice(0, middle), output),
    right = mergeSort(arr.slice(middle), output)
  const sorted = []
  let i = 0,
    j = 0
  while (i < left.length || j < right.length) {
    if (i >= left.length) {
      sorted.push(right[j])
      j++
    } else if (j >= right.length) {
      sorted.push(left[i])
      i++
    } else {
      if (left[i][0] > right[j][0]) {
        sorted.push(left[i])
        output[left[i][1]] += right.length - j
        i++
      } else {
        sorted.push(right[j])
        j++
      }
    }
  }

  return sorted
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
nums = [-1]

Output

x
+
cmd
[0]

#5 Code Example with Python Programming

Code - Python Programming


class Solution:
    def countSmaller(self, nums):
        r = []
        for i in range(len(nums) - 1, -1, -1):
            bisect.insort(r, nums[i])
            nums[i] = bisect.bisect_left(r, nums[i])
        return nums
Copy The Code & Try With Live Editor

Input

x
+
cmd
nums = [-1,-1]

Output

x
+
cmd
[0,0]

#6 Code Example with C# Programming

Code - C# Programming


using System.Collections.Generic;

namespace LeetCode
{
    public class _0315_CountOfSmallerNumbersAfterSelf
    {
        public IList < int> CountSmaller(int[] nums)
        {
            if (nums.Length == 0) return nums;

            int[] counts = new int[nums.Length];
            Node root = new Node(nums[nums.Length - 1]);

            for (int i = nums.Length - 2; i >= 0; i--)
                counts[i] = Insert(root, nums[i]);

            return counts;
        }

        private int Insert(Node root, int value)
        {
            if (value  <  root.Value)
            {
                root.LessCount++;
                if (root.Left == null)
                {
                    root.Left = new Node(value);
                    return 0;
                }
                return Insert(root.Left, value);
            }
            else if (root.Value  <  value)
            {
                if (root.Right == null)
                {
                    root.Right = new Node(value);
                    return root.EqualCount + root.LessCount;
                }
                return root.EqualCount + root.LessCount + Insert(root.Right, value);
            }
            else
            {
                root.EqualCount++;
                return root.LessCount;
            }
        }

        public class Node
        {
            public int Value;
            public int EqualCount = 1;
            public int LessCount = 0;

            public Node Left;
            public Node Right;

            public Node(int value)
            {
                this.Value = value;
            }
        }
    }
}
Copy The Code & Try With Live Editor

Input

x
+
cmd
nums = [-1,-1]

Output

x
+
cmd
[0,0]
Advertisements

Demonstration


Previous
#313 Leetcode Super Ugly Number Solution in C, C++, Java, JavaScript, Python, C# Leetcode
Next
#316 Leetcode Remove Duplicate Letters Solution in C, C++, Java, JavaScript, Python, C# Leetcode