常用排序算法:
快速排序
1 package LeetCode.test4_paixusuanfa.demo; 2 3 import java.util.Arrays; 4 5 /** 6 * 快速排序 7 * 将小于基准数的放置于基准数左边,大于基准数的放置于基准数右边 8 */ 9 public class 快速排序 { 10 public static void main(String[] args) { 11 int[] num = {7, 1, 3, 5, 13, 9, 3, 6, 11}; 12 quick_sort(num, 0, num.length - 1); 13 System.out.println(Arrays.toString(num)); 14 } 15 16 public static void quick_sort(int[] num, int l, int r) { 17 if (l > r) { 18 return; 19 } 20 int left = l; 21 int right = r; 22 int res = num[left]; 23 while (left < right) { 24 while (left < right && num[right] >= res) { 25 right--; 26 } 27 if (left < right) { 28 num[left] = num[right]; 29 } 30 while (left < right && num[left] <= res) { 31 left++; 32 } 33 if (left < right) { 34 num[right] = num[left]; 35 } 36 if (left == right) { 37 num[left] = res; 38 } 39 } 40 quick_sort(num, l, right - 1); 41 quick_sort(num, right + 1, r); 42 } 43 }
归并排序
1 package LeetCode.test4_paixusuanfa.demo; 2 3 import java.util.Arrays; 4 5 public class 归并排序 { 6 public static void main(String[] args) { 7 int[] num = {7, 1, 3, 5, 13, 9, 3, 6, 11}; 8 int[] temp = new int[num.length]; 9 merge_sort(num, temp, 0, num.length - 1); 10 System.out.println(Arrays.toString(num)); 11 } 12 13 public static void merge_sort(int[] num, int[] temp, int left, int right) { 14 if (left < right) { 15 int mid = left + ((right - left) >> 1); 16 merge_sort(num, temp, left, mid); //左边归并排序,使得左子序列有序 17 merge_sort(num, temp, mid + 1, right); //右边归并排序,使得右子序列有序 18 merge(num, temp, mid, left, right); //将两个有序子数组合并操作 19 } 20 } 21 22 public static void merge(int[] num, int[] temp, int mid, int left, int right) { 23 int i = left; 24 int j = mid + 1; 25 int t = 0; 26 while (i <= mid && j <= right) { 27 if (num[i] < num[j]) { 28 temp[t++] = num[i++]; 29 } else { 30 temp[t++] = num[j++]; 31 } 32 } 33 while (i <= mid) { //将左边剩余元素填充进temp中 34 temp[t++] = num[i++]; 35 } 36 while (j <= right) { //将右序列剩余元素填充进temp中 37 temp[t++] = num[j++]; 38 } 39 t = 0; 40 while (left <= right) { //将temp中的元素全部拷贝到原数组中 41 num[left++] = temp[t++]; 42 } 43 } 44 }
插入排序
1 package LeetCode.test4_paixusuanfa.demo; 2 3 import java.util.Arrays; 4 5 public class 插入排序 { 6 public static void main(String[] args) { 7 int[] num = {7, 1, 3, 5, 13, 9, 3, 6, 11}; 8 insert_sort(num); 9 System.out.println(Arrays.toString(num)); 10 } 11 12 public static void insert_sort(int[] num) { 13 for (int i = 1; i < num.length; i++) { 14 for (int j = i; j > 0; j--) { 15 if (num[j] < num[j - 1]) { 16 int temp = num[j]; 17 num[j] = num[j - 1]; 18 num[j - 1] = temp; 19 } 20 } 21 } 22 } 23 }
冒泡排序
1 package LeetCode.test4_paixusuanfa.demo; 2 3 import java.util.Arrays; 4 5 public class 冒泡排序 { 6 public static void main(String[] args) { 7 int[] num = {7, 2, 3, 5, 13, 9, 3, 1, 6, 11}; 8 bubble_sort(num); 9 System.out.println(Arrays.toString(num)); 10 } 11 12 public static void bubble_sort(int[] num) { 13 for (int j = 0; j < num.length; j++) { 14 for (int i = j+1; i < num.length; i++) { 15 if (num[i] < num[j]) { 16 int temp = num[i]; 17 num[i] = num[j]; 18 num[j] = temp; 19 } 20 } 21 } 22 } 23 }
选择排序
1 package LeetCode.test4_paixusuanfa.demo; 2 3 import java.util.Arrays; 4 5 public class 选择排序 { 6 public static void main(String[] args) { 7 int[] num = {7, 2, 3, 5, 13, 9, 3, 1, 6, 11}; 8 select_sort(num); 9 System.out.println(Arrays.toString(num)); 10 } 11 12 public static void select_sort(int[] num) { 13 for (int i = 0; i < num.length; i++) { 14 int res = i; 15 for (int j = i + 1; j < num.length; j++) { 16 if (num[j] < num[res]) { 17 res = j; 18 } 19 } 20 int temp = num[res]; 21 num[res] = num[i]; 22 num[i] = temp; 23 } 24 } 25 }
1、寻找两个正序数组的中位数
问题:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。
算法的时间复杂度应该为 O(log (m+n)) 。
示例 1:
输入:nums1 = [1,3], nums2 = [2]
输出:2.00000
解释:合并数组 = [1,2,3] ,中位数 2
示例 2:
输入:nums1 = [1,2], nums2 = [3,4]
输出:2.50000
解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5
示例 3:
输入:nums1 = [0,0], nums2 = [0,0]
输出:0.00000
示例 4:
输入:nums1 = [], nums2 = [1]
输出:1.00000
示例 5:
输入:nums1 = [2], nums2 = []
输出:2.00000
1 package LeetCode.test4_paixusuanfa; 2 3 public class ques_4_寻找两个正序数组的中位数 { 4 public static void main(String[] args) { 5 int[] nums1 = {1, 2}; 6 int[] nums2 = {3, 4}; 7 System.out.println(findMedianSortedArrays(nums1, nums2)); 8 } 9 10 public static double findMedianSortedArrays(int[] nums1, int[] nums2) { 11 int[] temp = new int[nums1.length + nums2.length]; 12 int t = 0, n1 = 0, n2 = 0; 13 while (n1 < nums1.length && n2 < nums2.length) { 14 temp[t++] = nums1[n1] < nums2[n2] ? nums1[n1++] : nums2[n2++]; 15 } 16 while (n1 < nums1.length) { 17 temp[t++] = nums1[n1++]; 18 } 19 while (n2 < nums2.length) { 20 temp[t++] = nums2[n2++]; 21 } 22 int l = nums1.length + nums2.length; 23 int mid = l / 2; 24 return l % 2 == 0 ? ((double)(temp[mid - 1] + temp[mid])) / 2 : temp[mid]; 25 } 26 }
2、数组中的第K个最大元素
问题:给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
示例 1:
输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:
输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4
1 package LeetCode.test4_paixusuanfa; 2 3 public class ques_215_数组中的第K个最大元素 { 4 public static void main(String[] args) { 5 int[] nums = {3, 2, 1, 5, 6, 4}; 6 int k = 2; 7 System.out.println(findKthLargest(nums, k)); 8 } 9 10 public static int findKthLargest(int[] nums, int k) { 11 if (k > nums.length) { 12 return -1; 13 } 14 quick_sort(nums, k, 0, nums.length - 1); 15 return nums[k - 1]; 16 } 17 18 public static void quick_sort(int[] nums, int k, int l, int r) { 19 int left = l; 20 int right = r; 21 int res = nums[left]; 22 while (left < right) { 23 while (left < right && nums[right] <= res) { 24 right--; 25 } 26 if (left < right) { 27 nums[left] = nums[right]; 28 } 29 while (left < right && nums[left] >= res) { 30 left++; 31 } 32 if (left < right) { 33 nums[right] = nums[left]; 34 } 35 if (left == right) { 36 nums[left] = res; 37 } 38 } 39 if ((k - 1) < right) { 40 quick_sort(nums, k, l, right - 1); 41 } else if ((k - 1) > right) { 42 quick_sort(nums, k, right + 1, r); 43 } 44 } 45 }
3、前K个高频元素
问题:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。
示例 1:
输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]
示例 2:
输入: nums = [1], k = 1
输出: [1]
1 package LeetCode.test4_paixusuanfa; 2 3 import java.util.*; 4 5 public class ques_347_前K个高频元素 { 6 public static void main(String[] args) { 7 int[] nums = {1, 1, 1, 2, 2, 3, 4}; 8 int k = 2; 9 System.out.println(Arrays.toString(topKFrequent(nums, k))); 10 } 11 12 public static int[] topKFrequent(int[] nums, int k) { 13 Map<Integer, Integer> map = new HashMap<>(); 14 for (Integer num : nums) { // 统计频率 15 map.put(num, map.getOrDefault(num, 0) + 1); 16 } // {1=3, 2=2, 3=1, 4=1} 17 18 //桶的索引指的就是元素的个数 eg:value值为3,就把1放在索引为3的桶里 19 List<Integer>[] bucket = new List[nums.length + 1]; 20 // 遍历map,根据value值放到对应的桶中 21 for (Map.Entry<Integer, Integer> e : map.entrySet()) { 22 Integer value = e.getValue(); 23 if (bucket[value] == null) { 24 bucket[value] = new ArrayList<>(); 25 } 26 bucket[value].add(e.getKey()); 27 } // [null, [3, 4], [2], [1], null, null, null, null] 28 29 List<Integer> list = new ArrayList<>(); 30 for (int i = bucket.length - 1; i >= 0 && list.size() < k; i--) { 31 if (bucket[i]!=null){ 32 list.addAll(bucket[i]); 33 } 34 } 35 int[] arr = new int[list.size()]; 36 for (int i = 0; i < list.size(); i++) { 37 arr[i] = list.get(i); 38 } 39 return arr; 40 } 41 }
4、根据字符出现频率排序
问题:给定一个字符串,请将字符串里的字符按照出现的频率降序排列。
示例 1:
输入:
"tree"
输出:
"eert"
解释:
'e'出现两次,'r'和't'都只出现一次。
因此'e'必须出现在'r'和't'之前。此外,"eetr"也是一个有效的答案。
示例 2:
输入:
"cccaaa"
输出:
"cccaaa"
解释:
'c'和'a'都出现三次。此外,"aaaccc"也是有效的答案。
注意"cacaca"是不正确的,因为相同的字母必须放在一起。
示例 3:
输入:
"Aabb"
输出:
"bbAa"
解释:
此外,"bbaA"也是一个有效的答案,但"Aabb"是不正确的。
注意'A'和'a'被认为是两种不同的字符。
1 package LeetCode.test4_paixusuanfa; 2 3 import java.util.*; 4 5 public class ques_451_根据字符出现频率排序 { 6 public static void main(String[] args) { 7 // String s = "Aabb"; 8 // String s = "tree"; 9 String s = "cccaaa"; 10 System.out.println(frequencySort(s)); 11 } 12 13 public static String frequencySort(String s) { 14 char[] chars = s.toCharArray(); 15 Map<Character, Integer> map = new HashMap<>(); 16 for (char c : chars) { // 统计频率 17 map.put(c, map.getOrDefault(c, 0) + 1); 18 } 19 20 List<Character>[] bucket = new List[chars.length + 1]; 21 for (Map.Entry<Character, Integer> m : map.entrySet()) { 22 Integer value = m.getValue(); 23 if (bucket[value] == null) { 24 bucket[value] = new ArrayList<>(); 25 } 26 bucket[value].add(m.getKey()); 27 } 28 29 List<Character> list = new ArrayList<>(); 30 for (int i = bucket.length - 1; i >= 0; i--) { 31 if (bucket[i] != null) { 32 for (int j = 0; j < bucket[i].size(); j++) { 33 for (int k = 0; k < i; k++) { 34 list.add(bucket[i].get(j)); 35 } 36 } 37 } 38 } 39 StringBuilder res = new StringBuilder(); 40 for (Character c : list) { 41 res.append(c); 42 } 43 return res.toString(); 44 } 45 }
5、颜色分类
问题:给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例 2:
输入:nums = [2,0,1]
输出:[0,1,2]
示例 3:
输入:nums = [0]
输出:[0]
示例 4:
输入:nums = [1]
输出:[1]
1 package LeetCode.test4_paixusuanfa; 2 3 import java.util.Arrays; 4 5 public class ques_75_颜色分类 { 6 public static void main(String[] args) { 7 int[] nums = {2, 0, 2, 1, 1, 0}; 8 sortColors(nums); 9 System.out.println(Arrays.toString(nums)); 10 } 11 12 public static void sortColors(int[] nums) { 13 quick_sort(nums, 0, nums.length - 1); 14 } 15 16 public static void quick_sort(int[] nums, int l, int r) { 17 if (l > r) { 18 return; 19 } 20 int left = l; 21 int right = r; 22 int res = nums[left]; 23 while (left < right) { 24 while (left < right && nums[right] >= res) { 25 right--; 26 } 27 if (left < right) { 28 nums[left] = nums[right]; 29 } 30 while (left < right && nums[left] <= res) { 31 left++; 32 } 33 if (left < right) { 34 nums[right] = nums[left]; 35 } 36 if (left == right) { 37 nums[left] = res; 38 } 39 } 40 quick_sort(nums, l, right - 1); 41 quick_sort(nums, right + 1, r); 42 } 43 }