Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Day 88 】2021-12-06 - 451 根据字符出现频率排序 #107

Open
azl397985856 opened this issue Dec 5, 2021 · 89 comments
Open

【Day 88 】2021-12-06 - 451 根据字符出现频率排序 #107

azl397985856 opened this issue Dec 5, 2021 · 89 comments

Comments

@azl397985856
Copy link
Contributor

451 根据字符出现频率排序

入选理由

暂无

题目地址

https://leetcode-cn.com/problems/sort-characters-by-frequency/comments/

前置知识

  • 排序算法
  • 哈希表

题目描述

给定一个字符串,请将字符串里的字符按照出现的频率降序排列。

示例 1:

输入:
"tree"

输出:
"eert"

解释:
'e'出现两次,'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。
示例 2:

输入:
"cccaaa"

输出:
"cccaaa"

解释:
'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。
示例 3:

输入:
"Aabb"

输出:
"bbAa"

解释:
此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。
@yanglr
Copy link

yanglr commented Dec 5, 2021

思路:

基于哈希表 + sort来做

代码:

实现语言: C++

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> dict;
        for (auto& ch : s)
        {
            if (dict.find(ch) == dict.end())
                dict[ch] = 1;
            else dict[ch]++;
        }
        string res;
        vector<pair<char, int>> kvVect;
        for (auto& kvp : dict)
            kvVect.push_back(kvp);        
        auto cmp = [](const pair<char, int>& p1, const pair<char, int>& p2)
        {
            return p1.second > p2.second;
        };
        sort(kvVect.begin(), kvVect.end(), cmp);
        for (auto& kvp : kvVect)
        {
            while (kvp.second--)
                res.push_back(kvp.first);
        } 
        return res;
    }
};

复杂度分析:

  • 时间复杂度: O(N logN)
  • 空间复杂度: O(N)

@muimi
Copy link

muimi commented Dec 5, 2021

代码

class Solution {
  public String frequencySort(String s) {
    HashMap<Character, Integer> map = new HashMap<>();
    for (char c : s.toCharArray()) {
      int frequency = map.getOrDefault(c, 0) + 1;
      map.put(c, frequency);
    }
    StringBuilder sb = new StringBuilder();
    List<Character> list = new ArrayList<>(map.keySet());
    Collections.sort(list, (a, b) -> map.get(b) - map.get(a));
    for (Character c : list) {
      int frequency = map.get(c);
      while (frequency-- > 0) sb.append(c);
    }
    return sb.toString();
  }
}

@ysy0707
Copy link

ysy0707 commented Dec 5, 2021

思路:堆+哈希表

class Solution {
    public String frequencySort(String s) {
        //利用大顶堆来排序,哈希表记录字符出现的次数
        HashMap<Character,Integer> map = new HashMap<>();
        PriorityQueue<Character> queue = new PriorityQueue<Character>((a, b) -> map.get(b) - map.get(a));


        //哈希表记录各个字符出现频次
        for(int i = 0; i < s.length(); i++){
            map.put(s.charAt(i), map.getOrDefault(s.charAt(i), 0) + 1);
        }

        //入堆
        for(char c: map.keySet()){
            queue.offer(c);
        }

        //存放结果
        StringBuilder sb = new StringBuilder();
        //取出堆中元素,已经排好大小
        while(!queue.isEmpty()){
            char c = queue.poll();
            int count = map.get(c);

            for(int i = 0; i < count; i++){
                sb.append(c);
            }

        }
        return sb.toString();
    }
}

时间复杂度: O(NlogN)
空间复杂度: O(N)

@thinkfurther
Copy link

class Solution:
    def frequencySort(self, s: str) -> str:
        fre = collections.Counter(s)
        
        fre_list = sorted(fre.items(), key = lambda x: x[1], reverse = True)
        
        result = ""

        for k, v in fre_list:
            result += k * v

        return result

@chenming-cao
Copy link

解题思路

堆+哈希表。建立哈希表储存字符和字符出现的频率。建立大顶堆,将哈希表中的字符放入堆中,然后每次从堆中取出当前出现频率最高的字符,加入到StringBuilder。最后返回字符串即可。

代码

class Solution {
    public String frequencySort(String s) {
        Map<Character, Integer> map = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        PriorityQueue<Character> heap = new PriorityQueue<>((a, b) -> map.get(b) - map.get(a));
        for (char key : map.keySet()) {
            heap.offer(key);
        }
        StringBuilder sb = new StringBuilder();
        while (!heap.isEmpty()) {
            char cur = heap.poll();
            int count = map.get(cur);
            while (count > 0) {
                sb.append(cur);
                count--;
            }
        }       
        return sb.toString();
    }
}

复杂度分析

  • 时间复杂度:O(n + klogk),n为字符串s的长度,k为s中不同字符的个数
  • 空间复杂度:O(k)

@zhangzz2015
Copy link

  • 比较直接,先建立hash table,得到每个字符的频率,后对频率进行排序后输出。使用multimap进行排序,也可使用最大堆进行排序。时间复杂度为O(n),后面的排序操作因为字符个数只有52,基本为O(1),空间复杂度为hash table的大小,因为自由只有52,也为O(1)。

关键点

代码

  • 语言支持:C++

C++ Code:

class Solution {
public:
    string frequencySort(string s) {
        
        unordered_map<char, int> record; 
        for(int i=0; i< s.size(); i++)
        {
            record[s[i]]++; 
        }
        multimap<int, char, greater<int>> sortNum; 
        for(auto it = record.begin(); it!=record.end(); it++)
        {
            sortNum.insert(make_pair((*it).second, (*it).first));
        }
        string ret; 
        for(auto it = sortNum.begin(); it!= sortNum.end(); it++)
        {
            for(int i=0; i< (*it).first; i++)
                ret.push_back((*it).second); 
        }
        
        return ret; 
        
    }
};

@ZacheryCao
Copy link

Idea

Heap + Hash table. The hash table is used to record the frequency of the char in the string. The heap is used to sort the char based on its frequency. Each node in the heap will be a tuple containing with two elements: the negative value of the char's frequency and char. The build the answer based on the heap.

Code:

class Solution:
    def frequencySort(self, s: str) -> str:
        count = collections.Counter(s)
        heap = []
        for i in count:
            heapq.heappush(heap, (-count[i], i))
        ans = ""
        while heap:
            i, c = heapq.heappop(heap)
            ans += abs(i) *c
        return ans

Complexity:

Time: O(N + k log k) N: length of the string. K: amount of the unique chars.
Space: O(k). Hash table is O(k). Heap is O(k)

@yingliucreates
Copy link

link:

https://leetcode.com/problems/sort-characters-by-frequency/

代码 Javascript

const frequencySort = function (s) {
  let seen = {};
  for (let char of s) {
    seen[char] ? seen[char]++ : (seen[char] = 1);
  }

  let SortedCharactersArray = Object.keys(seen).sort(
    (a, b) => seen[b] - seen[a]
  );

  let result = '';

  for (let char of SortedCharactersArray) result += char.repeat(seen[char]);

  return result;
};

@pophy
Copy link

pophy commented Dec 5, 2021

思路

  • 桶排序
  • 先用map <char, count> 统计每个单词出现次数
  • 建立大小为n的bucket,遍历map中的count, 如果count != 0,则bucket[n]加入char
  • 最后逆序遍历bucket 如果bucket[i] != null 收集答案

Java Code

    public String frequencySort(String s) {
        int n = s.length();
        Map<Character, Integer> countMap = new HashMap();
        for (char c : s.toCharArray()) {
            countMap.put(c, countMap.getOrDefault(c, 0) + 1);
        }
        List<Character>[] buckets = new ArrayList[n + 1];
        for (char c : countMap.keySet()) {
            if (buckets[countMap.get(c)] == null) {
                buckets[countMap.get(c)] = new ArrayList<>();
            }
            buckets[countMap.get(c)].add(c);
        }
        StringBuilder sb = new StringBuilder();
        for (int i = n; i >=0; i--) {
            if (buckets[i] != null) {
                for (char c : buckets[i]) {
                    for (int j = 0; j < i; j++) {
                        sb.append(c);
                    }
                }
            }
        }
        return sb.toString();
    }

时间&空间

  • 时间 O(n)
  • 空间 O(n)

@wenjialu
Copy link

wenjialu commented Dec 5, 2021

method 1:

thought

hash + sorted

code

class Solution:
    def frequencySort(self, s: str) -> str:
        #hash: key: char; value: times
        # sorted by value. return key 
        hash = {}
        
        for char in s:
           hash[char] = hash.get(char, 0) + 1
        # print(hash)   
        sorted_hash = sorted(hash.items(), key = lambda x: x[1], reverse = True) 
        print(sorted_hash)
        res = ""  
        for char, freq in sorted_hash:
            # for _ in range(freq):
            #     res += char
            res += char * freq
        return res         

complexity

Time: O(N+KlogK) N: length of s, K: num of diff chars in s (== num of keys in hash); logK??
space: O(N + K)


method2

thought

Bucket sorting

complexity

Time: O(N+ K) N: length of s, K: num of diff chars in s (== num of keys in hash)
space: O(N + K)

@biancaone
Copy link

biancaone commented Dec 5, 2021

class Solution:
    def frequencySort(self, s: str) -> str:
        counter = {}
        res = ''
        
        for char in s:
            counter[char] = counter.get(char, 0) + 1
            
        for char, count in sorted(counter.items(), key = lambda x: -x[1]):
            res += char * count
            
        return res

@skinnyh
Copy link

skinnyh commented Dec 5, 2021

Note

  • Count each char's frequency and sort chars based on the frequency.

Solution

class Solution:
    def frequencySort(self, s: str) -> str:
        d = {}
        for c in s:
            d[c] = d.get(c, 0) + 1
        tmp = sorted(d.items(), key=lambda x: x[1], reverse=True)
        res = ''
        for k, v in tmp:
            res += k * v
        return res

Time complexity: O(NlogN)

Space complexity: O(N)

@yuxiangdev
Copy link

Naive Approach

public String frequencySort(String s) {
        Map<Character, Integer> map = new HashMap<>();
        for (char c : s.toCharArray()) {
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        
        List<Character> letterOrder = new ArrayList<>(map.keySet());
        Collections.sort(letterOrder, (a, b) -> (map.get(b) - map.get(a)));
        
        StringBuilder sb = new StringBuilder();
        for (char c : letterOrder) {
            int frequency = map.get(c);
            for (int i = 0; i < frequency; i++) {
                sb.append(c);
            }
        }
        
        String res = sb.toString();
        return res;
    }

@yan0327
Copy link

yan0327 commented Dec 5, 2021

func frequencySort(s string) string {
    hash := map[byte]int{}
    for i:= range s{
        hash[s[i]]++
    }
    type pair struct{
        ch byte
        count int
    }
    pairs := make([]pair,len(hash))
    for k,v := range hash{
        pairs = append(pairs,pair{k,v})
    }
    sort.Slice(pairs,func(i,j int)bool{
        return pairs[i].count > pairs[j].count
    })
    out := ""
    for _,x := range pairs{
        out += strings.Repeat(string(x.ch),x.count)
    }
    return out
}

@Daniel-Zheng
Copy link

思路

哈希表。

代码(C++)

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> mp;
        int length = s.length();
        for (auto &ch : s) mp[ch]++;
        vector<pair<char, int>> vec;
        for (auto &it : mp) vec.emplace_back(it);
        sort(vec.begin(), vec.end(), [](const pair<char, int> &a, const pair<char, int> &b) {
            return a.second > b.second;
        });
        string ret;
        for (auto &[ch, num] : vec) for (int i = 0; i < num; i++) ret.push_back(ch);
        return ret;
    }
};

复杂度分析

  • 时间复杂度:O(N + KLogK)
  • 空间复杂度:O(N + K)

@kidexp
Copy link

kidexp commented Dec 6, 2021

thoughts

先计数,然后根据计数逆序排序 最后拼装

code

from collections import defaultdict
class Solution:
    def frequencySort(self, s: str) -> str:
        char_count_dict = defaultdict(int)
        for char in s:
            char_count_dict[char] += 1
        char_freq_sorted_list = sorted(char_count_dict.items(), key=lambda item: item[1], reverse = True)
        result = ''
        for char, freq in char_freq_sorted_list:
            result  += freq * char
        return result

complexity

Time O(nlgn)

Space O(n)

@wangzehan123
Copy link

代码

  • 语言支持:Java

Java Code:

public class Solution {
    /**
     * @param s: 
     * @return: return a string
     */
    public String frequencySort(String s) {
        Map<Character, Integer> frequency = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
            if (!frequency.containsKey(s.charAt(i))) {
                frequency.put(s.charAt(i), 0);
            }
            frequency.put(s.charAt(i), frequency.get(s.charAt(i)) + 1);
        }
        
        List<Pair> pairs = new LinkedList<Pair>();
        for (char key : frequency.keySet()) {
            pairs.add(new Pair(key, frequency.get(key)));
        }
        Collections.sort(pairs, new Comparator<Pair>() {
            public int compare(Pair a, Pair b) {
                if (a.frequency == b.frequency) {
                    return (int)a.letter - (int)b.letter;
                }
                return b.frequency - a.frequency;
            }
        });
        
        StringBuffer result = new StringBuffer("");
        for (Pair pair : pairs) {
            for (int i = 0; i < pair.frequency; i++) {
                result.append(pair.letter);
            }
        }
        
        return result.toString();
    }
}

class Pair {
    char letter;
    int frequency;
    public Pair(char letter, int frequency) {
        this.letter = letter;
        this.frequency = frequency;
    }
    
}

@naivecoder-irl
Copy link

    public String frequencySort(String s) {
        int n = s.length();
        Map<Character, Integer> countMap = new HashMap();
        for (char c : s.toCharArray()) {
            countMap.put(c, countMap.getOrDefault(c, 0) + 1);
        }
        List<Character>[] buckets = new ArrayList[n + 1];
        for (char c : countMap.keySet()) {
            if (buckets[countMap.get(c)] == null) {
                buckets[countMap.get(c)] = new ArrayList<>();
            }
            buckets[countMap.get(c)].add(c);
        }
        StringBuilder sb = new StringBuilder();
        for (int i = n; i >=0; i--) {
            if (buckets[i] != null) {
                for (char c : buckets[i]) {
                    for (int j = 0; j < i; j++) {
                        sb.append(c);
                    }
                }
            }
        }
        return sb.toString();
    }

@joeytor
Copy link

joeytor commented Dec 6, 2021

思路

使用堆进行排序

先对词频进行统计

然后将所有 (-frequency, character) 加入堆中 (因为想要大顶堆所以取负数)

然后每次从堆中取出堆顶元素赋值 frequency 遍加入 res string 中

from collections import Counter, defaultdict
import heapq
class Solution:
    def frequencySort(self, s: str) -> str:
        count = Counter(s)
        reverse = defaultdict(list)

        h = []

        for k, v in count.items():
            h.append((-v, k))
        
        heapq.heapify(h)
        res = ''
        
        while h:
            v, s = heapq.heappop(h)
            res += (-v)*s

        return res

复杂度

时间复杂度: O(nlogn) 堆的时间复杂度为 O(nlogn) 遍历统计的时间复杂度为 O(n)

空间复杂度: O(n) 堆的空间复杂度

@doveshnnqkl
Copy link

class Solution {
    public String frequencySort(String s) {
        Map<Character, Integer> map = new HashMap<Character, Integer>();
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);
            int frequency = map.getOrDefault(c, 0) + 1;
            map.put(c, frequency);
        }
        List<Character> list = new ArrayList<Character>(map.keySet());
        Collections.sort(list, (a, b) -> map.get(b) - map.get(a));
        StringBuffer sb = new StringBuffer();
        int size = list.size();
        for (int i = 0; i < size; i++) {
            char c = list.get(i);
            int frequency = map.get(c);
            for (int j = 0; j < frequency; j++) {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

@ghost
Copy link

ghost commented Dec 6, 2021

题目

  1. Sort Characters By Frequency

代码

class Solution:
    def frequencySort(self, s: str) -> str:
        d = collections.defaultdict(int)
        hq = []
        res = ''
        
        for char in s:
            d[char]-=1
        
        for k,v in d.items():
            heapq.heappush(hq, (v, k))
        
        while(hq):
            item = heapq.heappop(hq)
            res +=  -item[0] * item[1]
        
        return res
        

复杂度

Space: O(n)
Time: O(n + klogk)

@chun1hao
Copy link

chun1hao commented Dec 6, 2021

var frequencySort = function (s) {
  let map = new Map();
  for (let i of s) {
    let num = map.get(i) || 0;
    map.set(i, ++num);
  }
  let res = "";
  let arr = Array.from(map).sort((a, b) => b[1] - a[1]);
  for (let [key, val] of arr) {
    res += key.repeat(val);
  }
  return res;
};

@shawncvv
Copy link

shawncvv commented Dec 6, 2021

思路

链表

代码

Python3 Code

class Solution:
    def frequencySort(self, s: str) -> str:

        dict = {}
        for ch in s:
            dict[ch] = dict.get(ch, 0) + 1

        vals = sorted(dict.items(), key=lambda x : x[1], reverse=True)

        res = ""

        for k, v in vals:
            res += k * v

        return res

复杂度

设N为字符个数,K为去重字符个数

  • 时间复杂度:O(N+KlogK)
  • 空间复杂度:O(K)

@zszs97
Copy link

zszs97 commented Dec 6, 2021

开始刷题

题目简介

【Day 88 】2021-12-06 - 451 根据字符出现频率排序

题目思路

  • 按照出现频率排序

题目代码

代码块

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> mp;
        int length = s.length();
        for (auto &ch : s) {
            mp[ch]++;
        }
        vector<pair<char, int>> vec;
        for (auto &it : mp) {
            vec.emplace_back(it);
        }
        sort(vec.begin(), vec.end(), [](const pair<char, int> &a, const pair<char, int> &b) {
            return a.second > b.second;
        });
        string ret;
        for (auto &[ch, num] : vec) {
            for (int i = 0; i < num; i++) {
                ret.push_back(ch);
            }
        }
        return ret;
    }
};

复杂度

  • 空间复杂度 O(n+klogk)
  • 时间复杂度 O(n+k)

@okbug
Copy link

okbug commented Dec 6, 2021

思路

使用哈希表存,然后使用排序再拼接字符串

var frequencySort = function(s) {
    const map = new Map();

    for (let i = 0; i < s.length; i++) {
        let c = s[i];
        map.set(c, (map.get(c) || 0) + 1);
    }

    return Array.from(map)
        .sort((a, b) => b[1] - a[1])
        .map(item => item[0].repeat(item[1]))
        .join('')
};

@EggEggLiu
Copy link

思路

先遍历字符串获取词频哈希表,再将哈希表存到vector中来实现按value排序,最后拼接返回结果字符串

代码

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> mp;
        int length = s.length();
        for (auto &ch : s) {
            mp[ch]++;
        }
        vector<pair<char, int>> vec;
        for (auto &it : mp) {
            vec.emplace_back(it);
        }
        sort(vec.begin(), vec.end(), [](const pair<char, int> &a, const pair<char, int> &b) {
            return a.second > b.second;
        });
        string ret;
        for (auto &[ch, num] : vec) {
            for (int i = 0; i < num; i++) {
                ret.push_back(ch);
            }
        }
        return ret;
    }
};

复杂度

O(n + klogk)

@user1689
Copy link

user1689 commented Dec 6, 2021

题目

https://leetcode-cn.com/problems/sort-characters-by-frequency/

思路

Heap

python3

class Solution:
    def frequencySort(self, s: str) -> str:
        dic = defaultdict(int)
        for char in s:
            dic[char] += 1
        heap = []
        for key, value in dic.items():
            heapq.heappush(heap, (-value, key))
        ans = []
        while(heap):
            freq, char = heapq.heappop(heap)
            ans.append(-freq*char)
        return ''.join(ans)

复杂度分析

  • time nlogn
  • space n

相关题目

  1. 待补充

@LareinaWei
Copy link

Code

class Solution:
    def frequencySort(self, s: str) -> str:
        dic = {}
        for i in s:
            if i not in dic:
                dic[i] = 0
            dic[i] += 1
            
        sort = sorted(dic, key = dic.get, reverse = True)
        
        res = ""
        for k in sort:
            res += k * dic[k]
            
        return res

@guangsizhongbin
Copy link

guangsizhongbin commented Dec 6, 2021

func frequencySort(s string) string {
    m := make(map[rune]int)
    ret := make([]rune,0)//存放每一个字符
    res := make([]rune,0)//存放结果
    //注意!!要将s转成rune  因为使用for i,v:=range s的时候,这个v是rune的  最后return再转回来即可
    r := []rune(s)
    //这个for循环是得到string中每一个字符的频率,用一个数组存下字符
    for _,v := range r {
      //判断m这个map里面有没有v这个Key
        i,ok := m[v]
        if ok {//如果有的话则将m[v]的value+1 
            m[v] = i+1 // 即m[v]++
        }else{
            m[v] = 1
            ret = append(ret, v)
        }
    }
    //按照频率的大小排序
    sort.Slice(ret, func(i, j int) bool {
		return m[ret[i]] > m[ret[j]]
	})
    //按照频率将每个字符复原成字符串
    for i:=0;i<len(ret);i++{
        for j:=0;j<m[ret[i]];j++{
        res=append(res,ret[i])
        }
    }
    return string(res)
}

@machuangmr
Copy link

代码

class Solution {

    class Node{
        char c;
        int v;
        Node(char c, int v) {
            this.c = c;
            this.v = v;
        }
    }

    public String frequencySort(String s) {
        if(s.isEmpty()) return "";
        Map<Character, Integer> map = new HashMap<>();
        for(int i = 0;i < s.length();i++) {
            char temp = s.charAt(i);
            map.put(temp, map.getOrDefault(temp, 0) + 1);
        }
        PriorityQueue<Node> queue = new PriorityQueue<>( (a, b) -> {
            if(a.v != b.v) {
                return b.v -a.v;
            }
            return a.c - b.c;
        });
        for(char c : map.keySet()) {
            queue.add(new Node(c, map.get(c)));
        }
        StringBuilder sb = new StringBuilder(); 
        while(!queue.isEmpty()) {
            Node res = queue.poll();
            int value = res.v;
            while(value-- >0) {
                sb.append(res.c);
            }
        }
        return sb.toString();
    }
}

复杂度

  • 时间复杂度O(max(n, ClogC))
  • 空间复杂度O(n)

@hellowxwworld
Copy link

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> dict;
        for (auto& ch : s)
        {
            if (dict.find(ch) == dict.end())
                dict[ch] = 1;
            else dict[ch]++;
        }
        string res;
        vector<pair<char, int>> kvVect;
        for (auto& kvp : dict)
            kvVect.push_back(kvp);        
        auto cmp = [](const pair<char, int>& p1, const pair<char, int>& p2)
        {
            return p1.second > p2.second;
        };
        sort(kvVect.begin(), kvVect.end(), cmp);
        for (auto& kvp : kvVect)
        {
            while (kvp.second--)
                res.push_back(kvp.first);
        } 
        return res;
    }
};

@ymkymk
Copy link

ymkymk commented Dec 6, 2021

Map<Character, Integer> map = new HashMap<Character, Integer>();
int length = s.length();
for (int i = 0; i < length; i++) {
char c = s.charAt(i);
int frequency = map.getOrDefault(c, 0) + 1;
map.put(c, frequency);
}
List list = new ArrayList(map.keySet());
Collections.sort(list, (a, b) -> map.get(b) - map.get(a));
StringBuffer sb = new StringBuffer();
int size = list.size();
for (int i = 0; i < size; i++) {
char c = list.get(i);
int frequency = map.get(c);
for (int j = 0; j < frequency; j++) {
sb.append(c);
}
}
return sb.toString();

时间复杂度:O(n+klogk)
空间复杂度:O(n+k)

@yibenxiao
Copy link

【Day 88】451 根据字符出现频率排序

代码

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> mp;
        int length = s.length();
        for (auto &ch : s) {
            mp[ch]++;
        }
        vector<pair<char, int>> vec;
        for (auto &it : mp) {
            vec.emplace_back(it);
        }
        sort(vec.begin(), vec.end(), [](const pair<char, int> &a, const pair<char, int> &b) {
            return a.second > b.second;
        });
        string ret;
        for (auto &[ch, num] : vec) {
            for (int i = 0; i < num; i++) {
                ret.push_back(ch);
            }
        }
        return ret;
    }
};

复杂度

时间复杂度:O(NLogN)

空间复杂度:O(K)

@L-SUI
Copy link

L-SUI commented Dec 6, 2021

/**

  • @param {string} s
  • @return {string}
    */
    var frequencySort = function(s) {
    const mp = new Map();
    let maxFreq = 0;
    const length = s.length;
    for (const ch of s) {
    const frequency = (mp.get(ch) || 0) + 1;
    mp.set(ch, frequency);
    maxFreq = Math.max(maxFreq, frequency);
    }
    const buckets = new Array(maxFreq + 1).fill(0).map(() => new Array());
    for (const [ch, num] of mp.entries()) {
    buckets[num].push(ch);
    }
    const ret = [];
    for (let i = maxFreq; i > 0; i--) {
    const bucket = buckets[i];
    for (const ch of bucket) {
    for (let k = 0; k < i; k++) {
    ret.push(ch);
    }
    }
    }
    return ret.join('');
    };

@brainlds
Copy link

brainlds commented Dec 6, 2021

class Solution {
public String frequencySort(String s) {
int[] cc = new int[75];
Queue<int[]> queue = new PriorityQueue<>((a,b) -> b[0] - a[0] );
char[] c = s.toCharArray();
for(char ch : c) {
int ci = ch - '0';
cc[ci] ++;
}
for(int i = 0; i < 75 ; i ++) {
if(cc[i] != 0) {
queue.offer(new int[]{cc[i], i});
}
}
StringBuilder sb = new StringBuilder();
while(!queue.isEmpty()) {
int[] pair = queue.poll();
int ch = pair[0];
char cha = (char)('0' + pair[1]);
while(ch > 0) {
sb.append(cha);
ch --;
}
}
return sb.toString();
}
}

@chaggle
Copy link

chaggle commented Dec 6, 2021


title: "Day 87 23. 合并K个升序链表"
date: 2021-12-05T21:29:57+08:00
tags: ["Leetcode", "c++", "heap"]
categories: ["91-day-algorithm"]
draft: true


451. 根据字符出现频率排序

题目

给定一个字符串,请将字符串里的字符按照出现的频率降序排列。

示例 1:

输入:
"tree"

输出:
"eert"

解释:
'e'出现两次,'r''t'都只出现一次。
因此'e'必须出现在'r''t'之前。此外,"eetr"也是一个有效的答案。
示例 2:

输入:
"cccaaa"

输出:
"cccaaa"

解释:
'c''a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。
示例 3:

输入:
"Aabb"

输出:
"bbAa"

解释:
此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A''a'被认为是两种不同的字符。

题目思路

  • 1、如题目所说,手写一个cmp函数然后按照其中排序,返回其值即可。
class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> up;
        for(auto i : s) up[i]++;
        sort(s.begin(), s.end(), [&](const char &a, const char &b) {
            return up[a] == up[b] ? a > b : up[a] > up[b];
        });
        return s;
    }
};

复杂度

  • 时间复杂度:O(logn)
  • 空间复杂度:O(n)

@Zhang6260
Copy link

JAVA版本

思路:

直接使用堆来完成的,使用hashmap用来统计所有字母以及对应的个数,最后使用一个堆来完成排序,并输出。

class Solution {
    public String frequencySort(String abc) {
        //可以使是有堆(java中的优先队列来完成),来实现排序
        //统计使用  HashMap来完成
        if(abc.length()==0)return "";
         HashMap<Character,Integer> hashMap=new HashMap<>();
        for(int i=0;i<abc.length();i++){
            hashMap.put(abc.charAt(i),hashMap.getOrDefault(abc.charAt(i),0)+1);
        }
        //队列中存放  一个map
        PriorityQueue<int[]> queue=new PriorityQueue<>(new Comparator<int[]>() {
            @Override
            public int compare(int[] o1, int[] o2) {
                if(o1[0]!=o2[0])
                    return o2[1]-o1[1];
                else  return  o2[0]-o1[0];
            }
        });
        for(char temp:hashMap.keySet()){
            int f=hashMap.get(temp);
            queue.add(new int[]{temp,f});
        }
        StringBuilder stringBuilder = new StringBuilder();
        while (!queue.isEmpty()){
            int[]b=queue.poll();
            char t=(char)b[0];
            int num=b[1];
            for(int i=0;i<num;i++){
                stringBuilder.append(t);
            }
        }
        return stringBuilder.toString();
       
    }
}

时间复杂度:O(nlogn)

空间复杂度:O(n)

@biscuit279
Copy link

思路:哈希表,然后遍历这个哈希表

class Solution:
    def frequencySort(self, s: str) -> str:
        hash_map = {}
        ans = ''
        for i in s:
            if i not in hash_map:
                hash_map[i] = 0
            hash_map[i] += 1
        
        dict3 = sorted(hash_map.items(), key = lambda x : x[1], reverse = True)
        for item in dict3:
            ans += item[0]*item[1]
        return ans

时间复杂度:O(n)
空间复杂度:O(n)

@mokrs
Copy link

mokrs commented Dec 6, 2021

string frequencySort(string s) {
    unordered_map<char, int> mp;
    for (char &ch : s){
        ++mp[ch];
    }

    auto cmp = [](pair<char, int>& a, pair<char, int>& b){return a.second  <  b.second; };
    priority_queue<pair<char, int>, vector<pair<char, int>>, decltype(cmp)> q(cmp);

    for (unordered_map<char, int>::iterator it = mp.begin(); it != mp.end(); ++it){
        q.emplace(*it);
    }

    string res = "";
    while (!q.empty()){
        pair<char, int> p = q.top();
        q.pop();
        for (int i = 0; i < p.second; ++i){
            res += p.first;
        }			
    }

    return res;
}

@kkwu314
Copy link

kkwu314 commented Dec 6, 2021

思路

桶排序

代码

class Solution:
    def frequencySort(self, s: str) -> str:
        ret = []
        countFrequency = collections.defaultdict(int)
        for i in s:
            countFrequency[i] += 1
        buckets = [[] for _ in range(len(s) + 1)]
        for i in countFrequency:
            buckets[countFrequency[i]].extend(i*countFrequency[i])
        for i in buckets[::-1]:
            if(i):
                ret.extend(i)
        return ''.join(ret)

复杂度

时间:O(N)

空间:O(N)

@15691894985
Copy link

【Day 88】451 根据字符出现频率排序

https://leetcode-cn.com/problems/sort-characters-by-frequency/comments/

哈希解法

class Solution:
    def frequencySort(self, s: str) -> str:
        #哈希
        d ={}
        for i in s:
            if i not in d:
                d[i] = 0
            d[i] += 1
        sort1 = sorted(d,key= d.get,reverse=True)
        res = ""
        for k in sort1:
            res += k*d[k]
        return res

复杂度分析:

时间复杂度:O(n+klogk)

空间复杂度:O(k)

堆的解法:

  1. 还是哈希,只不过排序过程用堆
class Solution:
    def frequencySort(self, s: str) -> str:
        d= {}
        for i in s:
            d[i]= d.get(i,0)+1
            items = [(-val,key) for key,val in d.items()]
            heapq.heapify(items)
            res = ""
            while items:
                val, key = heapq.heappop(items)
                res += key*(-val)
            return res

时间复杂度:O(n+klogk)

空间复杂度:O(k)

@biscuit279
Copy link

思路:堆排序

import heapq
# Definition for singly-linked list.
# class ListNode:
#     def __init__(self, val=0, next=None):
#         self.val = val
#         self.next = next
class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        heap = []
        for i in lists:
            while i:
                heapq.heappush(heap,i.val)
                i = i.next

        d = c = ListNode(-1)
        while heap:
            c.next = ListNode(heapq.heappop(heap))
            c = c.next
        return d.next

时间复杂度:O(knlogk)
空间复杂度:O(n)

@shixinlovey1314
Copy link

Title:451. Sort Characters By Frequency

Question Reference LeetCode

Solution

Hash table + heap.

Code

class Solution {
public:
    void swap(pair<char,int>& a, pair<char, int>& b) {
        char ch = a.first;
        int cnt = a.second;
        
        a.first = b.first;
        a.second = b.second;
        
        b.first = ch;
        b.second = cnt;
    }
    
    void heap_push(std::vector<pair<char, int>> &heap, int& size, pair<char, int> val) {
        heap[++size] = val;
        int i = size;
        
        while (i > 1 && heap[i].second > heap[i / 2].second) {
            swap(heap[i], heap[i / 2]);
            i /= 2;
        }
    }
    
    int getBiggerChild(std::vector<pair<char, int>> &heap, int& size, int index) {
        int l = index * 2;
        int r = index * 2 + 1;
        
        if (r > size || heap[l].second > heap[r].second)
            return l;
        return r;
    }
    
    pair<char, int> heap_pop(std::vector<pair<char, int>> &heap, int& size) {
        pair<char, int> top = heap[1];
        swap(heap[1], heap[size--]);
        
        int i = 1;
        while (i <= size / 2) {
            int biggerChild = getBiggerChild(heap, size, i);
            if (heap[i].second >= heap[biggerChild].second) {
                break;
            }
            
            swap(heap[i], heap[biggerChild]);
            i = biggerChild;
        }
        
        
        return top;
    }
    
    string frequencySort(string s) {
        // Get the frequency of each character
        std::map<char, int> counter;
        for (char ch : s) {
            counter[ch]++;
        }
        
        // Setup Heap
        std::vector<pair<char, int>> heap(counter.size() + 1);
        int size = 0;
        
        // Initialize Heap.
        for (auto it = counter.begin(); it != counter.end(); it++) {
            heap_push(heap, size, make_pair(it->first, it->second));
        }
        
        // Generate result
        string result;
        while (size > 0) {
            pair<char, int> top = heap_pop(heap, size);
            result.append(string(top.second, top.first));
        }
        
        return result;
    }
};

Complexity

Time Complexity and Explanation

O(n): used to put each letter into the hash table, after that, since we have the limited number of upper and lower letters, the time to put into heap takes O(1)

Space Complexity and Explanation

O(1): we have 26 upper case letter, 26 lower case letter and 10 digits

@shanrufu
Copy link

shanrufu commented Dec 6, 2021

class Solution {
    public String frequencySort(String s) {
        int[] help = new int[123];

        for (char c: s.toCharArray()) {
            help[c]++;
        }

        PriorityQueue<int[]> queue = new PriorityQueue<>(122, (a, b) -> b[1] - a[1]);

        for (int i = 0; i < 123; i++) {
            if (help[i] > 0) {
                queue.add(new int[]{i, help[i]});
            }

        }

        StringBuilder sb = new StringBuilder();
        int[] cur;
        while (!queue.isEmpty()) {
            cur = queue.poll();
            for(int i = 0; i < cur[1]; i++) {
                sb.append((char)cur[0]);
            }
        }

        return sb.toString();
    }
}

@for123s
Copy link

for123s commented Dec 6, 2021

代码

  • 语言支持:C++

C++ Code:

class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> mp;
        int maxFreq = 0;
        int length = s.size();
        for (auto &ch : s) {
            maxFreq = max(maxFreq, ++mp[ch]);
        }
        vector<string> buckets(maxFreq + 1);
        for (auto &[ch, num] : mp) {
            buckets[num].push_back(ch);
        }
        string ret;
        for (int i = maxFreq; i > 0; i--) {
            string &bucket = buckets[i];
            for (auto &ch : bucket) {
                for (int k = 0; k < i; k++) {
                    ret.push_back(ch);
                }
            }
        }
        return ret;
    }
};

@jz1433
Copy link

jz1433 commented Dec 6, 2021

hashmap + sort

class Solution:
    def frequencySort(self, s: str) -> str:
        hashmap = collections.defaultdict(int)
        for char in s:
            hashmap[char] += 1
        sortedMap= sorted(hashmap.items(), key = lambda x: x[1], reverse = True)
        res = ''
        for key, val in sortedMap:
            res += key * val
        return res

@BreezePython
Copy link

思路

哈希表

代码

class Solution:
    def frequencySort(self, s):
        li = []
        for i, j in Counter(s).items():
            li.append([i, j])
        new_li = sorted(li, key=lambda x: -x[1])
        return ''.join([i * j for i,j in new_li])

复杂度

  • 时间复杂度:O(NlogN)
  • 空间复杂度:O(N)

@Yufanzh
Copy link

Yufanzh commented Dec 6, 2021

class Solution:
    def frequencySort(self, s: str) -> str:
        dict_map = collections.defaultdict(int)
        for i in s:
            dict_map[i] += 1
        
        item = [(-val, key) for (key, val) in dict_map.items()]
        heapq.heapify(item)
        res = ""
        while item:
            val, key = heapq.heappop(item)
            res += key * (-val)
        return res

@MonkofEast
Copy link

451. Sort Characters By Frequency

Click Me

Algo

Code

class Solution:
    def frequencySort(self, s: str) -> str:

        dict = {}
        for ch in s: dict[ch] = dict.get(ch, 0) + 1

        vals = sorted(dict.items(), key=lambda x : x[1], reverse=True)

        res = ""

        for k, v in vals: res += k * v

        return res

Comp

T: O(N+KlogK)

S: O(K)

@ChenJingjing85
Copy link

class Solution:
    def mergeKLists(self, lists: List[ListNode]) -> ListNode:
        heap = []
        for i in lists:
            while i:
                heapq.heappush(heap,i.val)
                i = i.next

        d = c = ListNode(-1)
        while heap:
            c.next = ListNode(heapq.heappop(heap))
            c = c.next
        return d.next

@ZETAVI
Copy link

ZETAVI commented Dec 6, 2021

class Solution {
    public String frequencySort(String s) {
        int[] cc = new int[75];
        Queue<int[]> queue = new PriorityQueue<>((a,b) -> b[0] - a[0] );
        char[] c = s.toCharArray();
        for(char ch : c) {
            int ci = ch - '0';
            cc[ci] ++;
        }
        for(int i = 0; i < 75 ; i ++) {
            if(cc[i] != 0) {
                queue.offer(new int[]{cc[i], i});
            }
        }
        StringBuilder sb = new StringBuilder();
        while(!queue.isEmpty()) {
            int[] pair = queue.poll();
            int ch = pair[0];
            char cha = (char)('0' + pair[1]);
            while(ch > 0) {
                sb.append(cha);
                ch --;
            }
        }
        return sb.toString();
    }
}

@taojin1992
Copy link

Logic:

# Plan 1:
map:
character - freq
add entry to maxHeap

s.length() = n
unique char = m

Time: O(n) + O(mlogm)
Space: 2*O(m) + O(n) = O(m+n)

# Plan 2:
bucket sort
map:
character - freq

freq corresponds to index of array
List<Character>[] charbuckets 

Time: O(s.length()) + O(unique letters) + O(s.length()) = O(s.length())
Space: map, List<Character>[] charbuckets, stringbuilder
O(s.length()) + O(unique letters)

Code:

class Solution {
    // plan 2
    public String frequencySort(String s) {
        StringBuilder sorted = new StringBuilder();
        Map<Character, Integer> charFreqMap = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
	        charFreqMap.put(s.charAt(i), charFreqMap.getOrDefault(s.charAt(i), 0) + 1);
        }
        List<Character>[] charbuckets = new List[s.length() + 1];// index means freq, 0--s.length()
        for (Map.Entry<Character, Integer> entry : charFreqMap.entrySet()) {
            int freq = entry.getValue(); // index
            if (charbuckets[freq] == null) {
                charbuckets[freq] = new ArrayList<>();
            }
            charbuckets[freq].add(entry.getKey());
        }
        // traverse the buckets
        for (int curFreq = s.length(); curFreq >= 0; curFreq--) {
            if (charbuckets[curFreq] != null) {
               for (char letter : charbuckets[curFreq]) {
                   for (int count = 0; count < curFreq; count++) {
                       sorted.append(letter);
                   }
               }
            }
            
        }
        return sorted.toString();
    }
    
    // plan 1
    public String frequencySort1(String s) {
        StringBuilder sorted = new StringBuilder();
        Map<Character, Integer> charFreqMap = new HashMap<>();
        for (int i = 0; i < s.length(); i++) {
	        charFreqMap.put(s.charAt(i), charFreqMap.getOrDefault(s.charAt(i), 0) + 1);
        }
        PriorityQueue<Map.Entry<Character, Integer>> maxHeap = new PriorityQueue<>((a, b) -> (b.getValue() - a.getValue()));
        maxHeap.addAll(charFreqMap.entrySet());
        while (!maxHeap.isEmpty()) {
	        Map.Entry<Character, Integer> entry = maxHeap.poll();
	        for (int i = 0; i < entry.getValue(); i++) {
		        sorted.append(entry.getKey());
	        }
        }
        return sorted.toString();
    }


}

@yj9676
Copy link

yj9676 commented Dec 6, 2021

class Solution {
    public String frequencySort(String s) {
        Map<Character, Integer> map = new HashMap<Character, Integer>();
        int length = s.length();
        for (int i = 0; i < length; i++) {
            char c = s.charAt(i);
            int frequency = map.getOrDefault(c, 0) + 1;
            map.put(c, frequency);
        }
        List<Character> list = new ArrayList<Character>(map.keySet());
        Collections.sort(list, (a, b) -> map.get(b) - map.get(a));
        StringBuffer sb = new StringBuffer();
        int size = list.size();
        for (int i = 0; i < size; i++) {
            char c = list.get(i);
            int frequency = map.get(c);
            for (int j = 0; j < frequency; j++) {
                sb.append(c);
            }
        }
        return sb.toString();
    }
}

@ginnydyy
Copy link

ginnydyy commented Dec 6, 2021

Problem

https://leetcode.com/problems/sort-characters-by-frequency/

Note

  • heap + hashmap

Solution

class Solution {
    public String frequencySort(String s) {
        if(s == null || s.isEmpty()){
            return s;
        }
        
        Map<Character, Integer> map = new HashMap<>();
        PriorityQueue<Character> q = new PriorityQueue<>((a, b) -> map.get(b) - map.get(a));
        
        for(char c: s.toCharArray()){
            map.put(c, map.getOrDefault(c, 0) + 1);
        }
        
        for(char c: map.keySet()){
            q.offer(c);
        }
        
        StringBuilder sb = new StringBuilder();
        
        while(!q.isEmpty()){
            char c = q.poll();
            for(int i = 0; i < map.get(c); i++){
                sb.append(c);
            }
        }
        
        return sb.toString();
    }
}

Complexity

  • T: O(n + klogk), n is the length of s, k is the number of unique characters in s. O(n) for scanning the s to calculate the frequencies. O(logk) is for each heap offer operation, there are k characters so need O(klogk). Overall is O(n + klogk).
  • S: O(k). Hashmap and heap are both in size k.

@joriscai
Copy link

joriscai commented Dec 7, 2021

思路

  • 建立map表
  • 再根据出现字符排序
  • 然后还原字符串

代码

javascript

/*
 * @lc app=leetcode.cn id=451 lang=javascript
 *
 * [451] 根据字符出现频率排序
 */

// @lc code=start
/**
 * @param {string} s
 * @return {string}
 */
var frequencySort = function(s) {
  const map = {}
  for (let i = 0; i < s.length; i++) {
    const char = s[i]
    map[char] = map[char] || 0
    map[char]++
  }

  const mapKeys = Object.keys(map)
  mapKeys.sort((a, b) => map[b] - map[a])

  let str = ''
  for (let i = 0; i < mapKeys.length; i++) {
    const char = mapKeys[i]
    const subStr = char.repeat(map[char])
    str += subStr
  }

  return str
};
// @lc code=end

复杂度分析

  • 时间复杂度:O(n + klogk), 先遍历字符串建立map表,n。对map表的key排序,klogk。再遍历map的key,k。总耗时为n + klogk + k。即O(n + klogk)
  • 空间复杂度:O(n + k),map表空间为k,生成的字符串为n。

@zhangyalei1026
Copy link

思路

hashmap + sort

代码

class Solution:
    def frequencySort(self, s: str) -> str:
        d = {}
        for chara in s:
            d[chara] = d.get(chara, 0) + 1
        new = list(d.items())
        sort_new = sorted(new, key = lambda x:x[1], reverse = True)
        result = ""
        for i in range(len(sort_new)):
            result += (sort_new[i][0] * sort_new[i][1])
        return result

复杂度分析

时间复杂度:O(nlogn)
空间复杂度: O(n)

@Bingbinxu
Copy link

思路
先构建一格哈系表,进行收集频率,然后对频率数进行排序
代码(C++)

实现语言: C++
class Solution {
public:
    string frequencySort(string s) {
        unordered_map<char, int> dict;
        for (auto& ch : s)
        {
            if (dict.find(ch) == dict.end())
                dict[ch] = 1;
            else dict[ch]++;
        }
        string res;
        vector<pair<char, int>> kvVect;
        for (auto& kvp : dict)
            kvVect.push_back(kvp);        
        auto cmp = [](const pair<char, int>& p1, const pair<char, int>& p2)
        {
            return p1.second > p2.second;
        };
        sort(kvVect.begin(), kvVect.end(), cmp);
        for (auto& kvp : kvVect)
        {
            while (kvp.second--)
                res.push_back(kvp.first);
        } 
        return res;
    }
};

复杂度分析
时间复杂度: O(NlogN)
空间复杂度: O(N)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests