刷题笔记
1370. Increasing Decreasing String
题目(这是一道虚假的easy题)
Given a string s. You should re-order the string using the following algorithm:
Pick the smallest character from s and append it to the result.
Pick the smallest character from s which is greater than the last appended character to the result and append it.
Repeat step 2 until you cannot pick more characters.
Pick the largest character from s and append it to the result.
Pick the largest character from s which is smaller than the last appended character to the result and append it.
Repeat step 5 until you cannot pick more characters.
Repeat the steps from 1 to 6 until you pick all characters from s.
In each step, If the smallest or the largest character appears more than once you can choose any occurrence and append it to the result.
Return the result string after sorting s with this algorithm.
思路
说在前面,这道题对我来说完全不easy,我最开始并没能写出来,并且看大神写的答案都看了一会才看明白。
- 首先要用到String的toCharArray()方法,将string转化为一个字符数组。
- 然后对字符数组中的字符进行计数,计数方法是在一个26位的数组中在相应位置++。
- 创建一个StringBuilder,对StringBuilder进行顺序和逆序交替append,并用while循环进行约束,约束条件为StringBuilder与s的长度。
- 顺序逆序交替append实现的方法,是通过一个三目运算符,来分别实现顺序和逆序判断每个字母位置上有没有剩下的数,如果有,则在StringBuilder后面append相应的字符;如果没有,就继续找下一个位置。
代码实现
class Solution {
public String sortString(String s) {
StringBuilder ans = new StringBuilder();
int[] count = new int[26];
int n = s.length();
for (char x : s.toCharArray()) {
count[x - 'a']++;
}
while (ans.length() < n) {
addToAns(count, ans, true);
addToAns(count, ans, false);
}
return ans.toString();
}
public static void addToAns (int[] count, StringBuilder ans, boolean b) {
for (int i = 0; i < 26; i++) {
int index = b ? i : 25 - i;
if (count[index]-- > 0) {
ans.append((char)(index + 'a'));
}
}
}
}
这种解法的速度太顶了。
其他解法:
public String sortString(String s) {
StringBuilder ans = new StringBuilder();
TreeMap<Character, Integer> tm = new TreeMap<>();
for (char c : s.toCharArray()) {
tm.put(c, 1 + tm.getOrDefault(c, 0));
}
boolean asc = true;
while (!tm.isEmpty()) {
for (char c : asc ? new TreeSet<>(tm.keySet()) : new TreeSet(tm.descendingKeySet())) {
ans.append(c);
tm.put(c, tm.get(c) - 1);
tm.remove(c, 0);
}
asc = !asc; // same as asc ^= true;
}
return ans.toString();
}
解法思路
- Use TreeMap to count each char in s;
- Append to StringBuilder the keys in TreeMap in sorted order, decrease the count of each key, and remove the entry if reaching 0;
- Do the similar operation in step 2, but in descending order of the keys;
- Repeat 2 and 3 till the TreeMap is empty.