LeetCode 767. 重构字符串

给定一个字符串S,检查是否能重新排布其中的字母,使得两相邻的字符不同。

若可行,输出任意可行的结果。若不可行,返回空字符串。

示例 1:

输入: S = “aab”
输出: “aba”

示例 2:

输入: S = “aaab”
输出: “”

若最大的字符数大于字符串长度加1的一半,则不可行
if (maxLen > (S.length + 1) / 2)
return “”;

方法一:
1.找出字符数最大的字符
2.将该字符填充字符串的偶数位置
3.将剩余字符依次填充字到符串中(中间要间隔一个其它字符)

class Solution {
	public String reorganizeString(String S) {
		//存储字符数
		int[] arr = new int[26];
		char[] chars = S.toCharArray();
		for (char ch : chars) {
			arr[ch - 'a']++;
		}
		// 找出最多数量的字符在arr中的索引
		int index = 0;
		for (int i = 1; i < arr.length; i++) {
			if (arr[i] > arr[index]) {
				index = i;
			}
		}
		//arr[index]为字符数最大的字符
		if (arr[index] > (S.length() + 1) / 2)
			return "";
		
		// 在偶数索引位置填充字符
		char[] newChar = new char[chars.length];
		int evenIndex = 0;
		while (arr[index] > 0) {
			newChar[evenIndex] = (char) (index + 'a');
			evenIndex += 2;
			arr[index]--;
		}
		
		// 再将剩余的字符添加到chars数组中
		int oddIndex = 1;
		for (int i = 0; i < 26; i++) {
			while (arr[i]-- > 0) {
				if (evenIndex < newChar.length) {
					newChar[evenIndex] = (char) (i + 'a');
					evenIndex += 2;
				} else {
					newChar[oddIndex] = (char) (i + 'a');
					oddIndex += 2;
				}
			}
		}

		return String.valueOf(newChar);
	}
}

方法二:
定义一个类 MyChar,类中定义两个属性,count (字符数),letter(字符)
采用最大堆的方式存储这个类,排序规则为根据count的大小,这里可以用优先队列PriorityQueue实现。每次去字符数最大的两个字符出来间隔排列。直至排完。

class MyChar {
	int count;
	char letter;

	public MyChar(int count, char letter) {
		this.count = count;
		this.letter = letter;
	}
}

class Solution {
	public String reorganizeString(String S) {
		// 存储每个字母的数量
		int[] arr = new int[26];
		char[] chars = S.toCharArray();

		for (char ch : chars) {
			arr[ch - 'a']++;
		}

		PriorityQueue<MyChar> queue = new PriorityQueue<>(new Comparator<MyChar>() {
			public int compare(MyChar ch1, MyChar ch2) {
				return ch2.count - ch1.count;
			}
		});

		int maxNum = 0;
		for (int i : arr) {
			if (i > maxNum)
				maxNum = i;
		}
		if (maxNum > (S.length() + 1) / 2)
			return "";

		for (int i = 0; i < 26; i++) {
			if (arr[i] != 0)
				queue.add(new MyChar(arr[i], (char) (i + 'a')));
		}

		StringBuilder sBuilder = new StringBuilder();
		while (queue.size() > 1) {
			MyChar c1 = queue.poll();
			MyChar c2 = queue.poll();

			sBuilder.append(c1.letter);
			sBuilder.append(c2.letter);

			if (--c1.count > 0)
				queue.add(c1);
			if (--c2.count > 0)
				queue.add(c2);
		}

		if (queue.size() > 0)
			sBuilder.append(queue.poll().letter);

		return sBuilder.toString();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值