按频率排序元素|集1

如果两个数字的频率相同,则以递减的频率打印数组中的元素,然后打印第一个数字。

null

例如:

Input:  arr[] = {2, 5, 2, 8, 5, 6, 8, 8}Output: arr[] = {8, 8, 8, 2, 2, 5, 5, 6}Input: arr[] = {2, 5, 2, 6, -1, 9999999, 5, 8, 8, 8}Output: arr[] = {8, 8, 8, 2, 2, 5, 5, 6, -1, 9999999}

方法1(使用排序)

  • 使用排序算法对元素进行排序 O(nlogn)
  • 扫描排序后的数组,并构建一个二维数组,其中包含元素和计数 O(n)。
  • 根据计数对2D数组进行排序 O(nlogn) .

例子:

  Input 2 5 2 8 5 6 8 8  After sorting we get  2 2 5 5 6 8 8 8  Now construct the 2D array as  2, 2  5, 2  6, 1  8, 3  Sort by count  8, 3  2, 2  5, 2  6, 1

如果频率相同,如何保持元素的顺序?

如果频率相同,上述方法无法确定元素的顺序。为了处理这个问题,我们应该在步骤3中使用索引,如果两个计数相同,那么我们应该首先处理(或打印)具有较低索引的元素。在步骤1中,我们应该存储索引而不是元素。

  Input   2  5  2  8  5  6  8  8  After sorting we get  Element 2 2 5 5 6 8 8 8  Index   0 2 1 4 5 3 6 7  Now construct the 2D array as  Index, Count  0,      2  1,      2  5,      1  3,      3  Sort by count (consider indexes in case of tie)  3, 3  0, 2  1, 2  5, 1    Print the elements using indexes in the above 2D array.

以下是上述方法的实施情况——

CPP

// Sort elements by frequency. If two elements have same
// count, then put the elements that appears first
#include <bits/stdc++.h>
using namespace std;
// Used for sorting
struct ele {
int count, index, val;
};
// Used for sorting by value
bool mycomp( struct ele a, struct ele b)
{
return (a.val < b.val);
}
// Used for sorting by frequency. And if frequency is same,
// then by appearance
bool mycomp2( struct ele a, struct ele b)
{
if (a.count != b.count)
return (a.count < b.count);
else
return a.index > b.index;
}
void sortByFrequency( int arr[], int n)
{
struct ele element[n];
for ( int i = 0; i < n; i++) {
// Fill Indexes
element[i].index = i;
// Initialize counts as 0
element[i].count = 0;
// Fill values in structure
// elements
element[i].val = arr[i];
}
/* Sort the structure elements according to value,
we used stable sort so relative order is maintained.
*/
stable_sort(element, element + n, mycomp);
/* initialize count of first element as 1 */
element[0].count = 1;
/* Count occurrences of remaining elements */
for ( int i = 1; i < n; i++) {
if (element[i].val == element[i - 1].val) {
element[i].count += element[i - 1].count + 1;
/* Set count of previous element as -1, we are
doing this because we'll again sort on the
basis of counts (if counts are equal than on
the basis of index)*/
element[i - 1].count = -1;
/* Retain the first index (Remember first index
is always present in the first duplicate we
used stable sort. */
element[i].index = element[i - 1].index;
}
/* Else If previous element is not equal to current
so set the count to 1 */
else
element[i].count = 1;
}
/* Now we have counts and first index for each element
so now sort on the basis of count and in case of tie
use index to sort.*/
stable_sort(element, element + n, mycomp2);
for ( int i = n - 1, index = 0; i >= 0; i--)
if (element[i].count != -1)
for ( int j = 0; j < element[i].count; j++)
arr[index++] = element[i].val;
}
// Driver program
int main()
{
int arr[] = { 2, 5, 2, 6, -1, 9999999, 5, 8, 8, 8 };
int n = sizeof (arr) / sizeof (arr[0]);
sortByFrequency(arr, n);
for ( int i = 0; i < n; i++)
cout << arr[i] << " " ;
return 0;
}


输出 :

8 8 8 2 2 5 5 6 -1 9999999

感谢Gaurav Ahirwar提供上述实施。

方法2(使用哈希和排序) 使用散列机制,我们可以将元素(也是第一个索引)及其计数存储在散列中。最后,根据哈希元素的计数对其进行排序。 以下是上述方法的实施情况-

CPP

// CPP program for above approach
#include <bits/stdc++.h>
using namespace std;
// Compare function
bool fcompare(pair< int , pair< int , int > > p,
pair< int , pair< int , int > > p1)
{
if (p.second.second != p1.second.second)
return (p.second.second > p1.second.second);
else
return (p.second.first < p1.second.first);
}
void sortByFrequency( int arr[], int n)
{
unordered_map< int , pair< int , int > > hash; // hash map
for ( int i = 0; i < n; i++) {
if (hash.find(arr[i]) != hash.end())
hash[arr[i]].second++;
else
hash[arr[i]] = make_pair(i, 1);
} // store the count of all the elements in the hashmap
// Iterator to Traverse the Hashmap
auto it = hash.begin();
// Vector to store the Final Sortted order
vector<pair< int , pair< int , int > > > b;
for (it; it != hash.end(); ++it)
b.push_back(make_pair(it->first, it->second));
sort(b.begin(), b.end(), fcompare);
// Printing the Sorted sequence
for ( int i = 0; i < b.size(); i++) {
int count = b[i].second.second;
while (count--)
cout << b[i].first << " " ;
}
}
// Driver Function
int main()
{
int arr[] = { 2, 5, 2, 6, -1, 9999999, 5, 8, 8, 8 };
int n = sizeof (arr) / sizeof (arr[0]);
sortByFrequency(arr, n);
return 0;
}


JAVA

/*package whatever //do not write package name here */
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
class GFG {
static Integer[] arr = { 2 , 5 , 2 , 8 , 5 , 6 , 8 , 8 };
// Driver Code
public static void main(String[] args)
{
List<Integer> list = Arrays.asList(arr);
sortBasedOnFrequencyAndValue(list);
}
// Compare Function
public static void
sortBasedOnFrequencyAndValue(List<Integer> list)
{
int n = arr.length;
final HashMap<Integer, Integer> mapCount
= new HashMap<Integer, Integer>();
final HashMap<Integer, Integer> mapIndex
= new HashMap<Integer, Integer>();
for ( int i = 0 ; i < n; i++) {
if (mapCount.containsKey(arr[i])) {
mapCount.put(arr[i],
mapCount.get(arr[i]) + 1 );
}
else {
mapCount.put(arr[i], 1 ); // Map to capture Count of elements
mapIndex.put(arr[i],i); // Map to capture 1st occurrence of elements
}
}
Collections.sort(list, new Comparator<Integer>() {
public int compare(Integer n1, Integer n2)
{
int freq1 = mapCount.get(n1);
int freq2 = mapCount.get(n2);
if (freq1 != freq2) {
return freq2 - freq1;
}
else {
return mapIndex.get(n1)
- mapIndex.get(
n2); // Elements with Lesser
// Index gets Higher
// Priority
}
}
});
System.out.println(list);
}
}


蟒蛇3

# Python program for above approach
from collections import defaultdict
# Sort by Frequency
def sortByFreq(arr, n):
# arr -> Array to be sorted
# n   -> Length of Array
# d is a hashmap(referred as dictionary in python)
d = defaultdict( lambda : 0 )
for i in range (n):
d[arr[i]] + = 1
# Sorting the array 'arr' where key
# is the function based on which
# the array is sorted
# While sorting we want to give
# first priority to Frequency
# Then to value of item
arr.sort(key = lambda x: ( - d[x], x))
return (arr)
# Driver Function
if __name__ = = "__main__" :
arr = [ 2 , 5 , 2 , 6 , - 1 , 9999999 , 5 , 8 , 8 , 8 ]
n = len (arr)
solution = sortByFreq(arr, n)
print ( * solution)


Javascript

<script>
let arr=[2, 5, 2, 6, -1, 9999999, 5, 8, 8, 8];
// Compare Function
function sortBasedOnFrequencyAndValue(list)
{
let n = arr.length;
let  mapCount
= new Map();
let  mapIndex
= new Map();
for (let i = 0; i < n; i++) {
if (mapCount.has(arr[i])) {
mapCount.set(arr[i],
mapCount.get(arr[i]) + 1);
}
else {
mapCount.set(arr[i],1); // Map to capture Count of elements
mapIndex.set(arr[i],i); // Map to capture 1st occurrence of elements
}
}
list.sort( function (n1,n2){
let freq1 = mapCount.get(n1);
let freq2 = mapCount.get(n2);
if (freq1 != freq2) {
return freq2 - freq1;
}
else {
return mapIndex.get(n1)
- mapIndex.get(
n2); // Elements with Lesser
// Index gets Higher
// Priority
}
});
document.write(list.join( " " ));
}
// Driver Code
sortBasedOnFrequencyAndValue(arr);
// This code is contributed by patel2127
</script>


输出 :

8 8 8 2 2 5 5 6 -1 9999999

这也可以通过使用两个映射来解决,一个用于数组元素作为索引,第二个映射之后的键是频率,值是数组元素。

方法3(使用BST和排序)

  • 在BST中逐个插入元素,如果元素已经存在,则增加节点的计数。二叉搜索树的节点(在这种方法中使用)如下所示。

C

struct tree {
int element;
int first_index /*To handle ties in counts*/
int count;
} BST;</ div >


JAVA

static class tree {
int element;
int first_index; /*To handle ties in counts*/
int count;
}
tree BST = new tree();
// This code is contributed by gauravrajput1


C#

public class tree {
public int element;
public int first_index; /* To handle ties in counts */
public int count;
}
tree BST = new tree();
// This code is contributed by gauravrajput1


  • 将第一个索引和相应的BST计数存储在2D数组中。
  • 根据计数对2D数组进行排序(如果是并列的,则使用索引)。

时间复杂性: O(nlogn)如果 自平衡二叉搜索树 被使用了。这是在中国实施的 第二组 . https://youtu.be/NBXf9vCksuM 第二组: 按频率排序元素|集2 如果您发现任何不正确的地方,或者您想分享有关上述主题的更多信息,请写评论

© 版权声明
THE END
喜欢就支持一下吧
点赞10 分享