腾讯笔试4:求字符串出现次数的最多和最少的k次

输入:

4 2
1
2
3
4

解释:4表示接下来输入4个字符串,2表示我们要找出现次数前2多和出现次数前2少的字符串,如果次数相同,根据字典序排序,字典序小的放前面。

然后下面的每一行都是输入的一个字符串。

因此输出为:

1 1
2 1
1 1
2 1


思路,本来遇到这种topk的自然想到小跟堆,但是最后输出是要按照出现次数进行排序的,小跟堆只能做到输出最大的k个,但是这k个并不会给你排好序,所以我就老老实实使用Arrays.sort()了,就是复制一下数组,然后分别应用两个比较器,一个比较器是:次数大的放前面,次数相同就根据字典序排序,另外一个比较器是:次数小的放前面,次数相同就根据字典序排序。

然后如何统计每个字符串的频率呢?这里我使用了一个hashmap,key是这个字符串,value是一个node类型,里面有这个字符串的内容str,以及这个字符串的次数。也就是一开始统计次数是在hashmap里面统计的,然后把里面的元素取出来做成一个node[]数组,然后把这个node[]数组来排序。

代码:

public static HashMap<String, Node> map;
	static class Node {
		public int times;
		public String str;
		public Node(int times, String str) {
			this.str = str;
			this.times = times;
		}
	}
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();// 一共几个字符串
		int k = sc.nextInt();// topk
		sc.nextLine();
		String[] strs = new String[n];
		map = new HashMap<>();
		for (int i = 0; i < n; i++) {
			strs[i] = sc.nextLine();
			if (!map.containsKey(strs[i])) {
				Node node = new Node(1, strs[i]);
				map.put(strs[i], node);
			}else{
				map.get(strs[i]).times++;
			}

		}
		Node[] nodes=new Node[map.size()];
		int index=0;
		for(Entry<String,Node> entry:map.entrySet()){
			nodes[index++]=entry.getValue();	
		}
		Node[] nodecopy=new Node[nodes.length];
		System.arraycopy(nodes, 0, nodecopy, 0, nodes.length);
		Arrays.sort(nodes,new Comparator<Node>(){//次数大的放前面,次数相同就根据字典序排序
			public int compare(Node node1,Node node2){
				if(node1.times!=node2.times){
					return node2.times-node1.times;
				}else{
					return node1.str.compareTo(node2.str);
				}
			}
		});
		Arrays.sort(nodecopy,new Comparator<Node>(){//次数小的放前面,次数相同就根据字典序排序
			public int compare(Node node1,Node node2){
				if(node1.times!=node2.times){
					return node1.times-node2.times;
				}else{
					return node1.str.compareTo(node2.str);
				}
			}
		});
		
		for(int i=0;i<k;i++){
			System.out.println(nodes[i].str+" "+nodes[i].times);
		}
		for(int i=0;i<k;i++){
			System.out.println(nodecopy[i].str+" "+nodecopy[i].times);
		}
		
		
	}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
腾讯 x 贝恩: 智慧零售私域白皮书2021》是一本关于智慧零售的研究报告,通过对当前零售行业趋势和未来发展进行深入分析,为企业提供了有关私域流量、数字化升级和用户运营的全面指导。 报告首先介绍了智慧零售的概念和重要性。智慧零售是指通过大数据、人工智能和物联网等技术手段,建立起信息化和智能化的零售生态系统,提升用户体验、运营效率和市场竞争力。 报告阐述了私域流量的重要性。私域流量是指企业通过数字化手段积累的用户,包括会员、社交媒体粉丝和线下会员等,具有较高的转化率和忠诚度。通过构建私域流量生态系统,企业可以深入了解用户需,精细化运营,并实现精准营销和增加复购率。 报告强调了数字化升级的必要性。随着消费者购物行为的变化,传统零售业务已经面临巨大挑战。报告提出了一系列数字化升级的策略,如建设多渠道零售平台、开展线上线下融合营销和提供智能化购物体验等。这些策略可以帮助企业提升运营效率、降低成本,并适应新形势下的市场需。 报告指出了用户运营的重要性。随着消费者需的多样化,企业需要开展个性化营销和定制化服务。报告提供了一些用户运营的方法和案例,如基于大数据的用户画像和行为分析、个性化推荐和定制化营销等。这些方法可以帮助企业更好地了解用户需,提供个性化的产品和服务,提升用户满意度和忠诚度。 总而言之,腾讯和贝恩通过《智慧零售私域白皮书2021》向企业推广了智慧零售的理念和策略。这本白皮书对私域流量、数字化升级和用户运营等方面进行了详细介绍,为企业提供了可行的解决方案,帮助它们在日益竞争激烈的零售市场中占据优势地位。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值