Approach
Sorting and greedy selection
For Count K-Subsequences of a String With Maximum Beauty Solved, the implementation first exposes a useful order, then scans that order while making locally justified choices.
- Choose the key that reveals the greedy or grouping structure.
- Sort the relevant records by that key.
- Scan in order, maintaining the invariant that makes each local choice safe.
Code notes
- 55 lines of Java from the credited upstream file 2842.java.
- The implementation visibly relies on sequence storage, hash lookup, ordered lookup.
- 5 loop blocks detected.
Complexity
Sorting is typically the dominant term unless the subsequent scan uses a more expensive nested operation.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
1class Solution {2 public int countKSubsequencesWithMaxBeauty(String s, int k) {3 Map<Character, Integer> count = new HashMap<>();4 for (final char c : s.toCharArray())5 count.merge(c, 1, Integer::sum);6 if (count.size() < k)7 return 0;8 9 long ans = 1;10 11 for (Pair<Integer, Integer> pair : getFreqCountPairs(count)) {12 final int fc = pair.getKey();13 final int numOfChars = pair.getValue();14 if (numOfChars >= k) {15 ans *= nCk(numOfChars, k) * modPow(fc, k);16 return (int) (ans % MOD);17 }18 ans *= modPow(fc, numOfChars);19 ans %= MOD;20 k -= numOfChars;21 }22 23 return (int) ans;24 }25 26 private static final int MOD = 1_000_000_007;27 28 private List<Pair<Integer, Integer>> getFreqCountPairs(Map<Character, Integer> count) {29 30 Map<Integer, Integer> freqCount = new HashMap<>();31 for (final int value : count.values())32 freqCount.merge(value, 1, Integer::sum);33 List<Pair<Integer, Integer>> freqCountPairs = new ArrayList<>();34 for (Map.Entry<Integer, Integer> entry : freqCount.entrySet())35 freqCountPairs.add(new Pair<>(entry.getKey(), entry.getValue()));36 freqCountPairs.sort((a, b) -> b.getKey().compareTo(a.getKey()));37 return freqCountPairs;38 }39 40 private long nCk(int n, int k) {41 long res = 1;42 for (int i = 1; i <= k; ++i)43 res = res * (n - i + 1) / i;44 return res;45 }46 47 private int modPow(long x, long n) {48 if (n == 0)49 return 1;50 if (n % 2 == 1)51 return (int) (x * modPow(x % MOD, (n - 1)) % MOD);52 return modPow(x * x % MOD, (n / 2)) % MOD;53 }54}55