牛客算法:字符串价值 随笔

首先附上自己比较蠢的方法,帮助理解。后面附上大神的代码。感受差距。

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
import java.util.*;
public class Main{
    public static void main(String[] args){
        try(Scanner in = new Scanner(System.in)){
            String s = in.next();
            int k = in.nextInt();
            System.out.println(helper(s,k));
        }
    }
    public static int helper(String s, int k){
        char []str = s.toCharArray();
        Arrays.sort(str);
        //统计有多少种字符
        int n = 1;
        for(int i = 0; i < str.length-1;i++) {
            if(str[i]!=str[i+1]) n++;
        }
        int []cnt = new int[n]; //存放各个字符的价值,如题中的4,2,1
        int cntt = 1; //统计各个字符串的价值
        for(int i = 1, j = 0; i < str.length;i++){
            if(str[i-1] == str[i] && i!=str.length-1){
                cntt++;
            }else{
                cnt[j] = cntt;
                cntt = 1;
                j++;
            }
        }
        cnt[n - 1]++;  //最后一个字符漏算,在循环外加上
         
        //去除k字符的核心思想是,每次总取最大的数减一,故减一次拍一次序
        Arrays.sort(cnt);
        for(int i = 0;i < k ; i++){
            cnt[cnt.length - 1] -= 1;
            Arrays.sort(cnt);
        }
        int sov = 0;
        for(int i = 0; i < cnt.length ; i++){
            sov += cnt[i]*cnt[i];
        }
         
        return sov;
         
    }
}

大神成程晨代码:

链接:https://www.nowcoder.com/questionTerminal/9240357eefcf4d938b90bdd5eec3712b
来源:牛客网

import java.util.*;
public class Main{
    public static void main(String[] args){
        try(Scanner in = new Scanner(System.in)){
            System.out.println(helper(in.next(),in.nextInt()));
        }
    }
    public static int helper(String s,int k){
        char[] cs = s.toCharArray();
        int[] a = new int[26];
        for(char c:cs){
            a[c - 'a']++;
        }
        //不用自己造轮子系列
        PriorityQueue<Integer> pq = new PriorityQueue<>((o1,o2)->{
            return o2 - o1;
        });
        for(int num:a){
            if(num != 0) pq.add(num);
        }
        int i = 0;
        while(i < k){
            int num = pq.remove();
            pq.add(num - 1);
            i++;
        }
        int sum = 0;
        for(int num:pq){
            sum += num * num;
        }
        return sum;
    }
}

首先巧妙的用这种减去字符a的方式,将数组中的各个字符进行统计。比自己遍历相互比较的方法好得多。

然后构造一个优先队列,然后利用其中的Comparator方法,进行倒序排序。每次通过remove取出第一个,即最大的值。然后减一,再加进来。重新队列倒序排序。循环操作。移除k个元素之后。打印字符串价值。

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄