不是最优解,基于自己能够理解的解法写,主要记录自己第一次刷力扣自己或者学习别人的答题思路
一、颜色分类
解题思路:使用双指针,一个用来交换0,一个用来交换2,每次当前指针移动的时候,先判断是否为2,如果为2就和记录2的指针交换位置,保证记录2的指针后面全是2,同理,记录0的指针保证左边全是0
public void sortColors(int[] nums) {
int left = 0; //记录0
int right = nums.length-1; //记录2
for(int i = 0 ; i < nums.length; i++){
while (i <= right && nums[i] == 2){
int temp = nums[i];
nums[i] = nums[right];
nums[right] = temp;
--right;
}
if (nums[i] == 0) {
int temp = nums[i];
nums[i] = nums[left];
nums[left] = temp;
++left;
}
}
}
二、数组中的第K个最大元素
解题思路:使用大顶堆进行排序,出队第k个即可
public int findKthLargest(int[] nums, int k) {
PriorityQueue<Integer> queue = new PriorityQueue<>(new Comparator<Integer>() {
@Override
public int compare(Integer o1, Integer o2) {
return o2 - o1;
}
});
for(int i = 0 ; i < nums.length; i ++){
queue.offer(nums[i]);
}
int result = 0;
for(int i = 0; i < k ; i++){
result = queue.poll();
}
return result;
}
三、根据字符出现频率排序
解题思路一:使用哈希存储字符和频率,在把频率作为桶下标存储字符,在循环append,下标就是频率次数
public static String frequencySort(String s) {
HashMap<Character,Integer> hashMap = new HashMap<>();
int max = 1;
for(int i = 0 ; i < s.length() ; i ++){
if(hashMap.containsKey(s.charAt(i))){
int count = hashMap.get(s.charAt(i))+1;
hashMap.put(s.charAt(i),count);
max = Math.max(max,count);
}else{
hashMap.put(s.charAt(i),1);
}
}
List<Character>[] list = new List[max+1];
for (Character key : hashMap.keySet()) {
int index = hashMap.get(key);
if(list[index] == null){
list[index] = new ArrayList<>();
}
list[index].add(key);
}
StringBuffer sb = new StringBuffer();
for(int i = list.length-1 ; i > -1 ; i--){
if(list[i] != null){
for(int j = 0 ; j < list[i].size() ;j++){
int pre = i;
while(pre > 0){
sb.append(list[i].get(j));
--pre;
}
}
}
}
return sb.toString();
}
解题思路二:使用大顶堆入队,在出队即可
public static String frequencySort2(String s) {
HashMap<Character,Integer> hashMap = new HashMap<>();
for(int i = 0 ; i < s.length() ; i ++){
if(hashMap.containsKey(s.charAt(i))){
int count = hashMap.get(s.charAt(i))+1;
hashMap.put(s.charAt(i),count);
}else{
hashMap.put(s.charAt(i),1);
}
}
PriorityQueue queue = new PriorityQueue(new Comparator() {
@Override
public int compare(Object o1, Object o2) {
int fre = hashMap.get(o2) - hashMap.get(o1);
return fre == 0? Character.compare((char)o1,(char)o2) : fre;
}
});
for (Character key : hashMap.keySet()) {
int frequency = hashMap.get(key);
for(int i = 0 ; i < frequency; i++){
queue.offer(key);
}
}
StringBuffer sb = new StringBuffer();
while(!queue.isEmpty()){
sb.append(queue.poll());
}
return sb.toString();
}
四、上升下降字符串
解题思路:想不出来!看的题解,只能说是米奇妙妙屋,妙到家了,因为只有小写字母,可以直接用桶来存储字符,在循环交替即可
public String sortString(String s) {
int[] bucket = new int[26];
for(int i = 0 ; i < s.length(); i++){
bucket[s.charAt(i) - 'a']++;
}
StringBuffer res = new StringBuffer();
while(res.length() < s.length()){
for(int i = 0 ; i < bucket.length; i++){
if(bucket[i] != 0) {
res.append((char)(i + 'a'));
bucket[i]--;
}
}
for(int i = 25 ; i >= 0; i--){
if(bucket[i] != 0) {
res.append((char)(i + 'a'));
bucket[i]--;
}
}
}
return res.toString();
}
五、非递增顺序的最小序列
解题思路:先用贪心,即判断最大的数是否能满足,所以肯定先排序,在找到满足的条件
设总数为total 子序列的和为nums -> 所以剩下的数的和为total-nums -> 根据题意满足 ->
total - nums < nums 所以 total < nums * 2
public static List<Integer> minSubsequence(int[] nums) {
int total = Arrays.stream(nums).sum();
int rights = 0;
List<Integer> list = new ArrayList<>();
//total 子序列=nums 剩下的是 total-nums 所以 total -nums < nums total < 2nums
Arrays.sort(nums);
for(int i = nums.length-1 ; i >= 0; i--){
rights += nums[i];
list.add(nums[i]);
if(total < 2 * rights){
break;
}
}
return list;
}
六、重新排列字符串
解题思路:因为了两个数组长度对应,直接用第二个数组做一个桶下标,放入对应的字符,在遍历append桶即可
public String restoreString(String s, int[] indices) {
char[] bucket = new char[indices.length];
for(int i = 0 ; i <s.length() ; i++){
bucket[indices[i]] = s.charAt(i);
}
StringBuffer res = new StringBuffer();
for(int i = 0 ; i < bucket.length; i++){
res.append(bucket[i]);
}
return res.toString();
}