给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
输入: [3,2,1,5,6,4], k = 2
输出: 5输入: [3,2,3,1,2,4,5,5,6], k = 4
输出: 4
这题可以考虑使用小根堆,维护数组中最大的k个数,遍历整个数组,然后输出小根堆堆顶元素就是所求元素。
时间复杂度为 O(nlogk),logk可以理解为常数项,将其忽略,所以时间复杂度近似为O(n)
public class test {public static void main(String[] args) {int[] arr=new int[]{3,2,3,1,2,4,5,5,6};int k=4;System.out.println(findKthLargest(arr,k));}public static int findKthLargest(int[] nums, int k) {if (k>nums.length){return 0;}//创建小根堆,k表示小根堆的大小,(a,b)->a-b表示构建小根堆,(a,b)->b-a表示构建大根堆PriorityQueue minHeap = new PriorityQueue<>(k,(a,b)->a-b);for (int i=0;iif (minHeap.size()//放入前k个元素minHeap.add(nums[i]);}else {//从第k+1个元素开始判断是否需要入堆if (minHeap.peek() < nums[i]) {minHeap.poll();minHeap.add(nums[i]);}}}return minHeap.peek();}
}
给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]输入: nums = [1], k = 1
输出: [1]
可以考虑首先使用一个map集合,key存nums中出现的元素,value存它们出现的次数
然后利用出现的次数构建一个小根堆,遍历map集合,得到最后的前k个高频元素
public class test {public static void main(String[] args) {int[] nums=new int[]{1,1,1,2,2,3};int k=2;int[] arr = topKFrequent(nums, k);for (int i=0;iSystem.out.println(arr[i]);}}public static int[] topKFrequent(int[] nums, int k) {HashMap map = new HashMap<>();for (int i=0;i//getOrDefault:如果map中存在传入的key,就返回此key的value,否则返回第二个参数0map.put(nums[i],map.getOrDefault(nums[i],0)+1 );}//以value建小根堆 [0]表示key [1]表示valuePriorityQueue queue = new PriorityQueue<>(new Comparator() {@Overridepublic int compare(int[] o1, int[] o2) {return o1[1]-o2[1];}});//遍历map集合,维护K个高频词的小根堆for (Map.Entry entry: map.entrySet()){//堆大小小于K时,元素直接入堆if (queue.size()queue.add(new int[]{entry.getKey(),entry.getValue()});}else {//堆大小>=K时,判断当前key的value是否大于堆顶元素的value,大于的话当前key和value入堆if (queue.peek()[1]< entry.getValue()){queue.poll();queue.add(new int[]{entry.getKey(),entry.getValue()});}}}int[] arr=new int[k];for (int i=0;i//将元素放入数组,然后返回arr[i]=queue.poll()[0];}return arr;}}
给定一个字符串 s ,根据字符出现的频率对其进行 降序排序 。一个字符出现频率是它出现在字符串中的次数。
返回已排序的字符串 。如果有多个答案,返回其中任何一个。
输入: s = "tree"
输出: "eert"
解释: 'e'出现两次,'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。输入: s = "cccaaa"
输出: "cccaaa"
解释: 'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。输入: s = "Aabb"
输出: "bbAa"
解释: 此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。
考虑可以将字符串转为字符数组,再将字符数组用map集合存储,key就是数组里的元素,value是他们出现的次数,
再将key存入list集合中,根据它们出现的次数给他们排序
public class test {public static void main(String[] args) {String s="tree";String s1 = frequencySort(s);System.out.println(s1);}public static String frequencySort(String s) {if (s==null||s.length()<1){return "";}char[] chars = s.toCharArray();HashMap map = new HashMap<>();//元素加入map集合for (int i=0;i//getOrDefault:如果map中存在传入的key,就返回此key的value,否则返回第二个参数0map.put(chars[i],map.getOrDefault(chars[i],0)+1);}//将map的所有的key存入到list集合中ArrayList list = new ArrayList<>(map.keySet());//根据value将list里的元素降序排序Collections.sort(list,(a,b)->map.get(b)-map.get(a));StringBuffer stringBuffer = new StringBuffer();//遍历list,取出key对应的value将它们拼成字符串for (int i=0;i//取出keychar c=list.get(i);//根据key查出value,也就是这个key的数量for (int j=0;j//拼接stringBuffer.append(c);}}return stringBuffer.toString();}
}
给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
必须在不使用库内置的 sort 函数的情况下解决这个问题。
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]输入:nums = [2,0,1]
输出:[0,1,2]
如果使用排序的话最好的使劲啊复杂度是O(nlogn),因为只有红白蓝三种颜色我们可以考虑使用指针的方式,在遍历到某个数
时,就将它移动到它应该去的位置。我们可以使用 zero来交换0 one来交换1,当0和1都到了合适的位置,那么2也是合适的(1)如果找到了1,就将其与nums[one]交换,并且将one向后移动一个位置
(2)如果找到了0,那么此时就有一个问题:当zero
public class test {public static void main(String[] args) {int[] arr=new int[]{2,0,2,1,1,0};sortColors(arr);for (int i=0;iSystem.out.println(arr[i]);}}public static void sortColors(int[] nums) {//初始化one和zero的位置int one=0;int zero=0;//遍历数组排序for (int i=0;iif (nums[i]==1){//如果nums[i]==1,交换它和nums[one],one++swap(nums,i,one);one++;} else if (nums[i]==0) {//交换nums[i]和nums[zero]swap(nums,i,zero);//如果zeroswap(nums,one,i);}//one和zero都后移一位one++;zero++;}}}public static void swap(int[] arr,int i,int j){int temp=arr[i];arr[i]=arr[j];arr[j]=temp;}
}