常用排序算法:

快速排序

 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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code

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 }
View Code
posted on 2021-11-30 23:13  晨曦生辉耀匕尖  阅读(52)  评论(0编辑  收藏  举报