. 重构字符串

 解题思路:1.先统计每个字母出现的次数  2. 按照次数由高到底排序  3. 先取最高,假设是a  4. 然后从次高中取

一个,组合起来,然后重新统计次数然后回到3。

	public String reorganizeString(String S) 
	{
		int n = S.length();
		// 键:字符,值:下标
		HashMap<Character, Integer> map = new HashMap<>();
		
		// 统计每个字符的出现次数
		for (int i=0; i<n; i++)
		{
			if (!map.containsKey(S.charAt(i)))
			{
				map.put(S.charAt(i), 1);
			}
			else
			{
				map.put(S.charAt(i), map.get(S.charAt(i))+1);
			}
		}
		
		ArrayList<Map.Entry<Character, Integer>> arrayList = new ArrayList<Map.Entry<Character, Integer>>(map.entrySet());
		// 根据value的大小,对Entry对象进行排序
		sortMap(arrayList);
		
		int max = arrayList.get(0).getValue(); // 出现最多的出现次数
		char maxi = arrayList.get(0).getKey(); // 出现次数最多的字符

		// 如果其他字符的出现次数+1 小于出现次数最多的字符的出现次数,则无法重构
		if (n-max+1 < max) 
		{
			return "";
		}
		
		// 重构字符串
		StringBuilder sBuilder = new StringBuilder();
		
		while (arrayList.size() > 1)
		{
			// 从最高字符中取一个
			Entry<Character, Integer> entry = arrayList.get(0);
			sBuilder.append(entry.getKey());
			entry.setValue(entry.getValue()-1);
			// 当前字符被用完
			if (entry.getValue() == 0)
			{
				arrayList.remove(entry);
			}
			
			if (arrayList.size() <= 1)
				break;
			
			// 从次高字符中取一个
			entry = arrayList.get(1);
			sBuilder.append(entry.getKey());
			entry.setValue(entry.getValue()-1);
			// 当前字符被用完
			if (entry.getValue() == 0)
			{
				arrayList.remove(entry);
			}
			
			// 重新排序(这里很重要)
			sortMap(arrayList);
		}
		
		// 处理arrayList中最后一个元素
		sBuilder.append(arrayList.get(arrayList.size()-1).getKey());
		
		return sBuilder.toString(); // aaa bbb ccc  abababccc
	}
	
	void sortMap(ArrayList<Map.Entry<Character, Integer>> arrayList)
	{
		// 根据value的大小,对Entry对象进行排序
		Collections.sort(arrayList, new Comparator<Map.Entry<Character, Integer>>()
		{
			@Override
			public int compare(Entry<Character, Integer> e1, Entry<Character, Integer> e2)
			{
				return e2.getValue().compareTo(e1.getValue());
			}
		});
	}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值