From 4a4d6154512cb47306e98b760f340e22f8db68f0 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Mon, 14 Jun 2021 19:16:52 +0800 Subject: [PATCH 1/4] feat: quick sort algorithm --- basic/sorting/QuickSort/Main.go | 45 ++++ basic/sorting/QuickSort/Main.java | 35 +++ basic/sorting/QuickSort/Main.js | 44 ++++ basic/sorting/QuickSort/Main.py | 26 +++ basic/sorting/QuickSort/QuickSort.go | 38 ---- basic/sorting/QuickSort/QuickSort.java | 44 ---- basic/sorting/QuickSort/QuickSort.js | 33 --- basic/sorting/QuickSort/README.md | 301 +++++++++++++++---------- 8 files changed, 337 insertions(+), 229 deletions(-) create mode 100644 basic/sorting/QuickSort/Main.go create mode 100644 basic/sorting/QuickSort/Main.java create mode 100644 basic/sorting/QuickSort/Main.js create mode 100644 basic/sorting/QuickSort/Main.py delete mode 100644 basic/sorting/QuickSort/QuickSort.go delete mode 100644 basic/sorting/QuickSort/QuickSort.java delete mode 100644 basic/sorting/QuickSort/QuickSort.js diff --git a/basic/sorting/QuickSort/Main.go b/basic/sorting/QuickSort/Main.go new file mode 100644 index 0000000000000..60f144e799932 --- /dev/null +++ b/basic/sorting/QuickSort/Main.go @@ -0,0 +1,45 @@ +package main + +import "fmt" + +func quickSort(nums []int, low, high int) { + if low >= high { + return + } + i, j := low-1, high+1 + x := nums[(low+high)>>1] + for i < j { + for { + i++ + if nums[i] >= x { + break + } + } + for { + j-- + if nums[j] <= x { + break + } + } + if i < j { + nums[i], nums[j] = nums[j], nums[i] + } + } + quickSort(nums, low, j) + quickSort(nums, j+1, high) +} + +func main() { + var n int + fmt.Scanf("%d\n", &n) + nums := make([]int, n) + for i := 0; i < n; i++ { + fmt.Scanf("%d", &nums[i]) + } + + quickSort(nums, 0, n-1) + + for _, v := range nums { + fmt.Printf("%d ", v) + } +} diff --git a/basic/sorting/QuickSort/Main.java b/basic/sorting/QuickSort/Main.java new file mode 100644 index 0000000000000..7d25358ebdf1c --- /dev/null +++ b/basic/sorting/QuickSort/Main.java @@ -0,0 +1,35 @@ +import java.util.Scanner; + +public class Main { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int[] nums = new int[n]; + for (int i = 0; i < n; ++i) { + nums[i] = sc.nextInt(); + } + quickSort(nums, 0, n - 1); + for (int i = 0; i < n; ++i) { + System.out.printf("%d ", nums[i]); + } + } + + public static void quickSort(int[] nums, int low, int high) { + if (low >= high) { + return; + } + int i = low - 1, j = high + 1; + int x = nums[low]; + while (i < j) { + while (nums[++i] < x); + while (nums[--j] > x); + if (i < j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; + } + } + quickSort(nums, low, j); + quickSort(nums, j + 1, high); + } +} \ No newline at end of file diff --git a/basic/sorting/QuickSort/Main.js b/basic/sorting/QuickSort/Main.js new file mode 100644 index 0000000000000..84d1d48c6d343 --- /dev/null +++ b/basic/sorting/QuickSort/Main.js @@ -0,0 +1,44 @@ +var buf = ''; + +process.stdin.on('readable', function () { + var chunk = process.stdin.read(); + if (chunk) buf += chunk.toString(); +}); + +let getInputArgs = line => { + return line.split(' ').filter(s => s !== '').map(x => parseInt(x)); +} + +function quickSort(nums, low, high) { + if (low >= high) { + return; + } + + let i = low - 1; + let j = high + 1; + let x = nums[(low + high) >> 1]; + while (i < j) { + while (nums[++i] < x); + while (nums[--j] > x); + if (i < j) { + const t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; + } + } + quickSort(nums, low, j); + quickSort(nums, j + 1, high); +} + + + +process.stdin.on('end', function () { + buf.split('\n').forEach(function (line, lineIdx) { + if (lineIdx % 2 === 1) { + nums = getInputArgs(line); + quickSort(nums, 0, nums.length - 1); + console.log(nums.join(' ')); + } + + }); +}); \ No newline at end of file diff --git a/basic/sorting/QuickSort/Main.py b/basic/sorting/QuickSort/Main.py new file mode 100644 index 0000000000000..8da08c820a8f5 --- /dev/null +++ b/basic/sorting/QuickSort/Main.py @@ -0,0 +1,26 @@ +N = int(input()) +nums = list(map(int, input().split())) + + +def quick_sort(nums, low, high): + if low >= high: + return + i, j = low - 1, high + 1 + x = nums[(low + high) >> 1] + while i < j: + while 1: + i += 1 + if nums[i] >= x: + break + while 1: + j -= 1 + if nums[j] <= x: + break + if i < j: + nums[i], nums[j] = nums[j], nums[i] + quick_sort(nums, low, j) + quick_sort(nums, j + 1, high) + + +quick_sort(nums, 0, N - 1) +print(' '.join(list(map(str, nums)))) diff --git a/basic/sorting/QuickSort/QuickSort.go b/basic/sorting/QuickSort/QuickSort.go deleted file mode 100644 index 8f24327e85a5c..0000000000000 --- a/basic/sorting/QuickSort/QuickSort.go +++ /dev/null @@ -1,38 +0,0 @@ -package main - -import "fmt" - -func partition(nums []int, low, high int) int { - pivot := nums[low] - for low < high { - for low < high && nums[high] >= pivot { - high-- - } - nums[low] = nums[high] - for low < high && nums[low] < pivot { - low++ - } - nums[high] = nums[low] - } - nums[low] = pivot - return low -} - -func _quickSort(nums []int, low, high int) { - if low >= high { - return - } - mid := partition(nums, low, high) - _quickSort(nums, low, mid) - _quickSort(nums, mid+1, high) -} - -func quickSort(nums []int) { - _quickSort(nums, 0, len(nums)-1) -} - -func main() { - nums := []int{1, 2, 7, 4, 5, 3} - quickSort(nums) - fmt.Println(nums) -} diff --git a/basic/sorting/QuickSort/QuickSort.java b/basic/sorting/QuickSort/QuickSort.java deleted file mode 100644 index 5ef3b307d79d5..0000000000000 --- a/basic/sorting/QuickSort/QuickSort.java +++ /dev/null @@ -1,44 +0,0 @@ -import java.util.Arrays; - -public class QuickSort { - - private static void quickSort(int[] nums) { - quickSort(nums, 0, nums.length - 1); - } - - private static void quickSort(int[] nums, int low, int high) { - if (low >= high) { - return; - } - int[] p = partition(nums, low, high); - quickSort(nums, low, p[0] - 1); - quickSort(nums, p[0] + 1, high); - } - - private static int[] partition(int[] nums, int low, int high) { - int less = low - 1, more = high; - while (low < more) { - if (nums[low] < nums[high]) { - swap(nums, ++less, low++); - } else if (nums[low] > nums[high]) { - swap(nums, --more, low); - } else { - ++low; - } - } - swap(nums, more, high); - return new int[] {less + 1, more}; - } - - private static void swap(int[] nums, int i, int j) { - int t = nums[i]; - nums[i] = nums[j]; - nums[j] = t; - } - - public static void main(String[] args) { - int[] nums = {1, 2, 7, 4, 5, 3}; - quickSort(nums); - System.out.println(Arrays.toString(nums)); - } -} \ No newline at end of file diff --git a/basic/sorting/QuickSort/QuickSort.js b/basic/sorting/QuickSort/QuickSort.js deleted file mode 100644 index e7a7bcae0ef31..0000000000000 --- a/basic/sorting/QuickSort/QuickSort.js +++ /dev/null @@ -1,33 +0,0 @@ -function quickSort(arr) { - let len = arr.length; - return qSort(arr, 0, len - 1); -} - -function qSort(arr, left, right) { - if (left < right) { - let index = partition(arr, left, right); - qSort(arr, left, index - 1); - qSort(arr, index + 1, right); - } - return arr; -} - -function partition(arr, left, right) { - let temp = arr[left]; - while (left < right) { - while (left < right && arr[right] > temp) { - right--; - } - arr[left] = arr[right]; - while (left < right && arr[left] <= temp) { - left++; - } - arr[right] = arr[left]; - } - arr[left] = temp; - console.log(arr) - return left; -} - -arr = [3, 5, 6, 2, 1, 7, 4]; -console.log(quickSort(arr)) diff --git a/basic/sorting/QuickSort/README.md b/basic/sorting/QuickSort/README.md index 6dc91311aa192..e41fc92af803a 100644 --- a/basic/sorting/QuickSort/README.md +++ b/basic/sorting/QuickSort/README.md @@ -1,96 +1,188 @@ # 快速排序 +## 题目描述 + +给定你一个长度为 `n` 的整数数列。 + +请你使用快速排序对这个数列按照从小到大进行排序。 + +并将排好序的数列按顺序输出。 + +**输入格式** + +输入共两行,第一行包含整数 n。 + +第二行包含 n 个整数(所有整数均在 1∼10^9 范围内),表示整个数列。 + +**输出格式** + +输出共一行,包含 n 个整数,表示排好序的数列。 + +**数据范围** + +1≤n≤100000 + +**输入样例:** + +``` +5 +3 1 2 4 5 +``` + +**输出样例:** + +``` +1 2 3 4 5 +``` + + +## 解法 + 快速排序也采用了分治的思想:把原始的数组筛选成较小和较大的两个子数组,然后递归地排序两个子数组。 -## 代码示例 +快排模板: + +```java +void quickSort(int[] nums, int low, int high) { + if (low >= high) { + return; + } + int i = low - 1, j = high + 1; + int x = nums[low]; + while (i < j) { + while (nums[++i] < x); + while (nums[--j] > x); + if (i < j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; + } + } + quickSort(nums, low, j); + quickSort(nums, j + 1, high); +} +``` +### **Python3** + +```python +N = int(input()) +nums = list(map(int, input().split())) + + +def quick_sort(nums, low, high): + if low >= high: + return + i, j = low - 1, high + 1 + x = nums[(low + high) >> 1] + while i < j: + while 1: + i += 1 + if nums[i] >= x: + break + while 1: + j -= 1 + if nums[j] <= x: + break + if i < j: + nums[i], nums[j] = nums[j], nums[i] + quick_sort(nums, low, j) + quick_sort(nums, j + 1, high) + + +quick_sort(nums, 0, N - 1) +print(' '.join(list(map(str, nums)))) +``` + ### **Java** ```java -import java.util.Arrays; - -public class QuickSort { +import java.util.Scanner; - private static void quickSort(int[] nums) { - quickSort(nums, 0, nums.length - 1); +public class Main { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int[] nums = new int[n]; + for (int i = 0; i < n; ++i) { + nums[i] = sc.nextInt(); + } + quickSort(nums, 0, n - 1); + for (int i = 0; i < n; ++i) { + System.out.printf("%d ", nums[i]); + } } - - private static void quickSort(int[] nums, int low, int high) { + + public static void quickSort(int[] nums, int low, int high) { if (low >= high) { return; } - int[] p = partition(nums, low, high); - quickSort(nums, low, p[0] - 1); - quickSort(nums, p[0] + 1, high); - } - - private static int[] partition(int[] nums, int low, int high) { - int less = low - 1, more = high; - while (low < more) { - if (nums[low] < nums[high]) { - swap(nums, ++less, low++); - } else if (nums[low] > nums[high]) { - swap(nums, --more, low); - } else { - ++low; + int i = low - 1, j = high + 1; + int x = nums[low]; + while (i < j) { + while (nums[++i] < x); + while (nums[--j] > x); + if (i < j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; } } - swap(nums, more, high); - return new int[] {less + 1, more}; - } - - private static void swap(int[] nums, int i, int j) { - int t = nums[i]; - nums[i] = nums[j]; - nums[j] = t; - } - - public static void main(String[] args) { - int[] nums = {1, 2, 7, 4, 5, 3}; - quickSort(nums); - System.out.println(Arrays.toString(nums)); + quickSort(nums, low, j); + quickSort(nums, j + 1, high); } } ``` + ### **JavaScript** ```js -function quickSort(arr) { - let len = arr.length; - return qSort(arr, 0, len - 1); -} +var buf = ''; -function qSort(arr, left, right) { - if (left < right) { - let index = partition(arr, left, right); - qSort(arr, left, index - 1); - qSort(arr, index + 1, right); - } - return arr; +process.stdin.on('readable', function () { + var chunk = process.stdin.read(); + if (chunk) buf += chunk.toString(); +}); + +let getInputArgs = line => { + return line.split(' ').filter(s => s !== '').map(x => parseInt(x)); } -function partition(arr, left, right) { - let temp = arr[left]; - while (left < right) { - while (left < right && arr[right] > temp) { - right--; - } - arr[left] = arr[right]; - while (left < right && arr[left] <= temp) { - left++; +function quickSort(nums, low, high) { + if (low >= high) { + return; + } + + let i = low - 1; + let j = high + 1; + let x = nums[(low + high) >> 1]; + while (i < j) { + while (nums[++i] < x); + while (nums[--j] > x); + if (i < j) { + const t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; } - arr[right] = arr[left]; } - arr[left] = temp; - console.log(arr) - return left; + quickSort(nums, low, j); + quickSort(nums, j + 1, high); } -arr = [3, 5, 6, 2, 1, 7, 4]; -console.log(quickSort(arr)) + +process.stdin.on('end', function () { + buf.split('\n').forEach(function (line, lineIdx) { + if (lineIdx % 2 === 1) { + nums = getInputArgs(line); + quickSort(nums, 0, nums.length - 1); + console.log(nums.join(' ')); + } + + }); +}); ``` ### **Go** @@ -100,66 +192,47 @@ package main import "fmt" -func partition(nums []int, low, high int) int { - pivot := nums[low] - for low < high { - for low < high && nums[high] >= pivot { - high-- +func quickSort(nums []int, low, high int) { + if low >= high { + return + } + i, j := low-1, high+1 + x := nums[(low+high)>>1] + for i < j { + for { + i++ + if nums[i] >= x { + break + } + } + for { + j-- + if nums[j] <= x { + break + } } - nums[low] = nums[high] - for low < high && nums[low] < pivot { - low++ + if i < j { + nums[i], nums[j] = nums[j], nums[i] } - nums[high] = nums[low] } - nums[low] = pivot - return low + quickSort(nums, low, j) + quickSort(nums, j+1, high) } -func _quickSort(nums []int, low, high int) { - if low >= high { - return +func main() { + var n int + fmt.Scanf("%d\n", &n) + nums := make([]int, n) + for i := 0; i < n; i++ { + fmt.Scanf("%d", &nums[i]) } - mid := partition(nums, low, high) - _quickSort(nums, low, mid) - _quickSort(nums, mid+1, high) -} -func quickSort(nums []int) { - _quickSort(nums, 0, len(nums)-1) -} + quickSort(nums, 0, n-1) -func main() { - nums := []int{1, 2, 7, 4, 5, 3} - quickSort(nums) - fmt.Println(nums) + for _, v := range nums { + fmt.Printf("%d ", v) + } } ``` - - -## 算法分析 - -空间复杂度 O(logn),时间复杂度 O(nlogn)。 - -对于规模为 n 的问题,一共要进行 log(n) 次的切分,和基准值进行 n-1 次比较,n-1 次比较的时间复杂度是 O(n),所以快速排序的时间复杂度为 O(nlogn)。 - -但是,如果每次在选择基准值的时候,都不幸地选择了子数组里的最大或最小值。即每次把把数组分成了两个更小长度的数组,其中一个长度为 1,另一个的长度是子数组的长度减 1。这样的算法复杂度变成 O(n²)。 - -和归并排序不同,快速排序在每次递归的过程中,只需要开辟 O(1) 的存储空间来完成操作来实现对数组的修改;而递归次数为 logn,所以它的整体空间复杂度完全取决于压堆栈的次数。 - -## 如何优化快速排序? - -前面讲到,最坏情况下快速排序的时间复杂度是 O(n²),实际上,这种 O(n²) 时间复杂度出现的主要原因还是因为我们基准值选得不够合理。最理想的基准点是:**被基准点分开的两个子数组中,数据的数量差不多**。 - -如果很粗暴地直接选择第一个或者最后一个数据作为基准值,不考虑数据的特点,肯定会出现之前讲的那样,在某些情况下,排序的最坏情况时间复杂度是 O(n²)。 - -有两个比较常用的分区算法。 - -### 1. 三数取中法 - -我们从区间的首、尾、中间,分别取出一个数,然后对比大小,取这 3 个数的中间值作为分区点。这样每间隔某个固定的长度,取数据出来比较,将中间值作为分区点的分区算法,肯定要比单纯取某一个数据更好。但是,如果要排序的数组比较大,那“三数取中”可能就不够了,可能要“五数取中”或者“十数取中”。 - -### 2. 随机法 - -随机法就是每次从要排序的区间中,随机选择一个元素作为分区点。这种方法并不能保证每次分区点都选的比较好,但是从概率的角度来看,也不大可能会出现每次分区点都选的很差的情况,所以平均情况下,这样选的分区点是比较好的。时间复杂度退化为最糟糕的 O(n²) 的情况,出现的可能性不大。 + \ No newline at end of file From 9a8b7a7b997b41a8be463689a7c719e70e355812 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Mon, 14 Jun 2021 20:34:31 +0800 Subject: [PATCH 2/4] feat: merge sort algorithm --- basic/sorting/MergeSort/Main.go | 49 ++++ basic/sorting/MergeSort/Main.java | 44 ++++ basic/sorting/MergeSort/Main.js | 52 +++++ basic/sorting/MergeSort/Main.py | 34 +++ basic/sorting/MergeSort/MergeSort.go | 46 ---- basic/sorting/MergeSort/MergeSort.java | 42 ---- basic/sorting/MergeSort/MergeSort.js | 19 -- basic/sorting/MergeSort/README.md | 305 ++++++++++++++++++------- basic/sorting/QuickSort/README.md | 2 +- 9 files changed, 401 insertions(+), 192 deletions(-) create mode 100644 basic/sorting/MergeSort/Main.go create mode 100644 basic/sorting/MergeSort/Main.java create mode 100644 basic/sorting/MergeSort/Main.js create mode 100644 basic/sorting/MergeSort/Main.py delete mode 100644 basic/sorting/MergeSort/MergeSort.go delete mode 100644 basic/sorting/MergeSort/MergeSort.java delete mode 100644 basic/sorting/MergeSort/MergeSort.js diff --git a/basic/sorting/MergeSort/Main.go b/basic/sorting/MergeSort/Main.go new file mode 100644 index 0000000000000..33c6941c0dfd9 --- /dev/null +++ b/basic/sorting/MergeSort/Main.go @@ -0,0 +1,49 @@ +package main + +import "fmt" + +func mergeSort(nums []int, low, high int) { + if low >= high { + return + } + mid := (low + high) >> 1 + mergeSort(nums, low, mid) + mergeSort(nums, mid+1, high) + i, j := low, mid+1 + tmp := make([]int, 0) + for i <= mid && j <= high { + if nums[i] <= nums[j] { + tmp = append(tmp, nums[i]) + i++ + } else { + tmp = append(tmp, nums[j]) + j++ + } + } + for i <= mid { + tmp = append(tmp, nums[i]) + i++ + } + for j <= high { + tmp = append(tmp, nums[j]) + j++ + } + for i, j = low, 0; i <= high; i, j = i+1, j+1 { + nums[i] = tmp[j] + } +} + +func main() { + var n int + fmt.Scanf("%d\n", &n) + nums := make([]int, n) + for i := 0; i < n; i++ { + fmt.Scanf("%d", &nums[i]) + } + + mergeSort(nums, 0, n-1) + + for _, v := range nums { + fmt.Printf("%d ", v) + } +} \ No newline at end of file diff --git a/basic/sorting/MergeSort/Main.java b/basic/sorting/MergeSort/Main.java new file mode 100644 index 0000000000000..0775465b6cc10 --- /dev/null +++ b/basic/sorting/MergeSort/Main.java @@ -0,0 +1,44 @@ +import java.util.Scanner; + +public class Main { + private static int[] tmp = new int[100010]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int[] nums = new int[n]; + for (int i = 0; i < n; ++i) { + nums[i] = sc.nextInt(); + } + mergeSort(nums, 0, n - 1); + for (int i = 0; i < n; ++i) { + System.out.printf("%d ", nums[i]); + } + } + + public static void mergeSort(int[] nums, int low, int high) { + if (low >= high) { + return; + } + int mid = (low + high) >>> 1; + mergeSort(nums, low, mid); + mergeSort(nums, mid + 1, high); + int i = low, j = mid + 1, k = 0; + while (i <= mid && j <= high) { + if (nums[i] <= nums[j]) { + tmp[k++] = nums[i++]; + } else { + tmp[k++] = nums[j++]; + } + } + while (i <= mid) { + tmp[k++] = nums[i++]; + } + while (j <= high) { + tmp[k++] = nums[j++]; + } + for (i = low, j = 0; i <= high; ++i, ++j) { + nums[i] = tmp[j]; + } + } +} \ No newline at end of file diff --git a/basic/sorting/MergeSort/Main.js b/basic/sorting/MergeSort/Main.js new file mode 100644 index 0000000000000..e311d66d7b47a --- /dev/null +++ b/basic/sorting/MergeSort/Main.js @@ -0,0 +1,52 @@ +var buf = ''; + +process.stdin.on('readable', function () { + var chunk = process.stdin.read(); + if (chunk) buf += chunk.toString(); +}); + +let getInputArgs = line => { + return line.split(' ').filter(s => s !== '').map(x => parseInt(x)); +} + +function mergeSort(nums, low, high) { + if (low >= high) { + return; + } + + const mid = (low + high) >> 1; + mergeSort(nums, low, mid); + mergeSort(nums, mid + 1, high); + let i = low; + let j = mid + 1; + let tmp = []; + while (i <= mid && j <= high) { + if (nums[i] <= nums[j]) { + tmp.push(nums[i++]); + } else { + tmp.push(nums[j++]); + } + } + while (i <= mid) { + tmp.push(nums[i++]); + } + while (j <= high) { + tmp.push(nums[j++]); + } + for (i = low, j = 0; i <= high; ++i, ++j) { + nums[i] = tmp[j]; + } +} + + + +process.stdin.on('end', function () { + buf.split('\n').forEach(function (line, lineIdx) { + if (lineIdx % 2 === 1) { + nums = getInputArgs(line); + mergeSort(nums, 0, nums.length - 1); + console.log(nums.join(' ')); + } + + }); +}); \ No newline at end of file diff --git a/basic/sorting/MergeSort/Main.py b/basic/sorting/MergeSort/Main.py new file mode 100644 index 0000000000000..30c9bab4358e9 --- /dev/null +++ b/basic/sorting/MergeSort/Main.py @@ -0,0 +1,34 @@ +N = int(input()) +nums = list(map(int, input().split())) + + +def merge_sort(nums, low, high): + if low >= high: + return + mid = (low + high) >> 1 + merge_sort(nums, low, mid) + merge_sort(nums, mid + 1, high) + tmp = [] + i, j = low, mid + 1 + while i <= mid and j <= high: + if nums[i] <= nums[j]: + tmp.append(nums[i]) + i += 1 + else: + tmp.append(nums[j]) + j += 1 + while i <= mid: + tmp.append(nums[i]) + i += 1 + while j <= high: + tmp.append(nums[j]) + j += 1 + + j = 0 + for i in range(low, high + 1): + nums[i] = tmp[j] + j += 1 + + +merge_sort(nums, 0, N - 1) +print(' '.join(list(map(str, nums)))) diff --git a/basic/sorting/MergeSort/MergeSort.go b/basic/sorting/MergeSort/MergeSort.go deleted file mode 100644 index c3d74bc191d58..0000000000000 --- a/basic/sorting/MergeSort/MergeSort.go +++ /dev/null @@ -1,46 +0,0 @@ -package main - -import "fmt" - -func merge(nums, temp []int, low, mid, high int) { - for i, j, k := low, mid+1, low; k <= high; k++ { - if i > mid { - temp[k] = nums[j] - j++ - } else if j > high { - temp[k] = nums[i] - i++ - } else if nums[i] <= nums[j] { - temp[k] = nums[i] - i++ - } else { - temp[k] = nums[j] - j++ - } - } - for i := low; i <= high; i++ { - nums[i] = temp[i] - } -} - -func _mergeSort(nums, temp []int, low, high int) { - if low >= high { - return - } - mid := low + (high-low)/2 - _mergeSort(nums, temp, low, mid) - _mergeSort(nums, temp, mid+1, high) - merge(nums, temp, low, mid, high) -} - -func mergeSort(nums []int) { - n := len(nums) - temp := make([]int, n) - _mergeSort(nums, temp, 0, n-1) -} - -func main() { - nums := []int{1, 2, 7, 4, 5, 3} - mergeSort(nums) - fmt.Println(nums) -} diff --git a/basic/sorting/MergeSort/MergeSort.java b/basic/sorting/MergeSort/MergeSort.java deleted file mode 100644 index d1f781ca9d347..0000000000000 --- a/basic/sorting/MergeSort/MergeSort.java +++ /dev/null @@ -1,42 +0,0 @@ -import java.util.Arrays; - -public class MergeSort { - - private static void merge(int[] nums, int low, int mid, int high, int[] temp) { - int i = low, j = mid + 1, k = low; - while (k <= high) { - if (i > mid) { - temp[k++] = nums[j++]; - } else if (j > high) { - temp[k++] = nums[i++]; - } else if (nums[i] <= nums[j]) { - temp[k++] = nums[i++]; - } else { - temp[k++] = nums[j++]; - } - } - - System.arraycopy(temp, low, nums, low, high - low + 1); - } - - private static void mergeSort(int[] nums, int low, int high, int[] temp) { - if (low >= high) { - return; - } - int mid = (low + high) >>> 1; - mergeSort(nums, low, mid, temp); - mergeSort(nums, mid + 1, high, temp); - merge(nums, low, mid, high, temp); - } - - private static void mergeSort(int[] nums) { - int[] temp = new int[nums.length]; - mergeSort(nums, 0, nums.length - 1, temp); - } - - public static void main(String[] args) { - int[] nums = {1, 2, 7, 4, 5, 3}; - mergeSort(nums); - System.out.println(Arrays.toString(nums)); - } -} \ No newline at end of file diff --git a/basic/sorting/MergeSort/MergeSort.js b/basic/sorting/MergeSort/MergeSort.js deleted file mode 100644 index a14a87df6eeae..0000000000000 --- a/basic/sorting/MergeSort/MergeSort.js +++ /dev/null @@ -1,19 +0,0 @@ -function mergeSort(arr) { - if (arr.length < 2) return arr; - let mid = Math.ceil(arr.length / 2); - let arrLeft = mergeSort(arr.splice(0, mid)); - let arrRight = mergeSort(arr.splice(-mid)); - return merge(arrLeft, arrRight); -} - -function merge(arr1, arr2) { - let arr = []; - while (arr1.length && arr2.length) { - arr.push(arr1[0] <= arr2[0] ? arr1.shift() : arr2.shift()); - } - return [...arr, ...arr1, ...arr2]; - -} - -arr = [3, 5, 6, 2, 1, 7, 4]; -console.log(mergeSort(arr)); \ No newline at end of file diff --git a/basic/sorting/MergeSort/README.md b/basic/sorting/MergeSort/README.md index 26eb45f2683b3..0a5af8c580317 100644 --- a/basic/sorting/MergeSort/README.md +++ b/basic/sorting/MergeSort/README.md @@ -1,57 +1,162 @@ # 归并排序 +## 题目描述 + +给定你一个长度为 `n` 的整数数列。 + +请你使用归并排序对这个数列按照从小到大进行排序。 + +并将排好序的数列按顺序输出。 + +**输入格式** + +输入共两行,第一行包含整数 n。 + +第二行包含 n 个整数(所有整数均在 1∼10^9 范围内),表示整个数列。 + +**输出格式** + +输出共一行,包含 n 个整数,表示排好序的数列。 + +**数据范围** + +1≤n≤100000 + +**输入样例:** + +``` +5 +3 1 2 4 5 +``` + +**输出样例:** + +``` +1 2 3 4 5 +``` + +## 解法 + 归并排序的核心思想是分治,把一个复杂问题拆分成若干个子问题来求解。 归并排序的算法思想是:把数组从中间划分为两个子数组,一直递归地把子数组划分成更小的数组,直到子数组里面只有一个元素的时候开始排序。排序的方法就是按照大小顺序合并两个元素。接着依次按照递归的顺序返回,不断合并排好序的数组,直到把整个数组排好序。 -## 代码示例 +归并排序模板: + +```java +void mergeSort(int[] nums, int low, int high) { + if (low >= high) { + return; + } + int mid = (low + high) >>> 1; + mergeSort(nums, low, mid); + mergeSort(nums, mid + 1, high); + int i = low, j = mid + 1, k = 0; + while (i <= mid && j <= high) { + if (nums[i] <= nums[j]) { + tmp[k++] = nums[i++]; + } else { + tmp[k++] = nums[j++]; + } + } + while (i <= mid) { + tmp[k++] = nums[i++]; + } + while (j <= high) { + tmp[k++] = nums[j++]; + } + for (i = low, j = 0; i <= high; ++i, ++j) { + nums[i] = tmp[j]; + } +} +``` +### **Python3** + +```python +N = int(input()) +nums = list(map(int, input().split())) + + +def merge_sort(nums, low, high): + if low >= high: + return + mid = (low + high) >> 1 + merge_sort(nums, low, mid) + merge_sort(nums, mid + 1, high) + tmp = [] + i, j = low, mid + 1 + while i <= mid and j <= high: + if nums[i] <= nums[j]: + tmp.append(nums[i]) + i += 1 + else: + tmp.append(nums[j]) + j += 1 + while i <= mid: + tmp.append(nums[i]) + i += 1 + while j <= high: + tmp.append(nums[j]) + j += 1 + + j = 0 + for i in range(low, high + 1): + nums[i] = tmp[j] + j += 1 + + +merge_sort(nums, 0, N - 1) +print(' '.join(list(map(str, nums)))) +``` + ### **Java** ```java -import java.util.Arrays; - -public class MergeSort { - - private static void merge(int[] nums, int low, int mid, int high, int[] temp) { - int i = low, j = mid + 1, k = low; - while (k <= high) { - if (i > mid) { - temp[k++] = nums[j++]; - } else if (j > high) { - temp[k++] = nums[i++]; - } else if (nums[i] <= nums[j]) { - temp[k++] = nums[i++]; - } else { - temp[k++] = nums[j++]; - } - } +import java.util.Scanner; - System.arraycopy(tmp, low, nums, low, high - low + 1); +public class Main { + private static int[] tmp = new int[100010]; + + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(); + int[] nums = new int[n]; + for (int i = 0; i < n; ++i) { + nums[i] = sc.nextInt(); + } + mergeSort(nums, 0, n - 1); + for (int i = 0; i < n; ++i) { + System.out.printf("%d ", nums[i]); + } } - - private static void mergeSort(int[] nums, int low, int high, int[] temp) { + + public static void mergeSort(int[] nums, int low, int high) { if (low >= high) { return; } int mid = (low + high) >>> 1; - mergeSort(nums, low, mid, temp); - mergeSort(nums, mid + 1, high, temp); - merge(nums, low, mid, high, temp); - } - - private static void mergeSort(int[] nums) { - int n = nums.length; - int[] temp = new int[n]; - mergeSort(nums, 0, n - 1, temp); - } - - public static void main(String[] args) { - int[] nums = {1, 2, 7, 4, 5, 3}; - mergeSort(nums); - System.out.println(Arrays.toString(nums)); + mergeSort(nums, low, mid); + mergeSort(nums, mid + 1, high); + int i = low, j = mid + 1, k = 0; + while (i <= mid && j <= high) { + if (nums[i] <= nums[j]) { + tmp[k++] = nums[i++]; + } else { + tmp[k++] = nums[j++]; + } + } + while (i <= mid) { + tmp[k++] = nums[i++]; + } + while (j <= high) { + tmp[k++] = nums[j++]; + } + for (i = low, j = 0; i <= high; ++i, ++j) { + nums[i] = tmp[j]; + } } } ``` @@ -59,25 +164,58 @@ public class MergeSort { ### **JavaScript** ```js -function mergeSort(arr) { - if (arr.length < 2) return arr; - let mid = Math.ceil(arr.length / 2); - let arrLeft = mergeSort(arr.splice(0, mid)); - let arrRight = mergeSort(arr.splice(-mid)); - return merge(arrLeft, arrRight); +var buf = ''; + +process.stdin.on('readable', function () { + var chunk = process.stdin.read(); + if (chunk) buf += chunk.toString(); +}); + +let getInputArgs = line => { + return line.split(' ').filter(s => s !== '').map(x => parseInt(x)); } -function merge(arr1, arr2) { - let arr = []; - while (arr1.length && arr2.length) { - arr.push(arr1[0] <= arr2[0] ? arr1.shift() : arr2.shift()); +function mergeSort(nums, low, high) { + if (low >= high) { + return; + } + + const mid = (low + high) >> 1; + mergeSort(nums, low, mid); + mergeSort(nums, mid + 1, high); + let i = low; + let j = mid + 1; + let tmp = []; + while (i <= mid && j <= high) { + if (nums[i] <= nums[j]) { + tmp.push(nums[i++]); + } else { + tmp.push(nums[j++]); + } + } + while (i <= mid) { + tmp.push(nums[i++]); + } + while (j <= high) { + tmp.push(nums[j++]); + } + for (i = low, j = 0; i <= high; ++i, ++j) { + nums[i] = tmp[j]; } - return [...arr, ...arr1, ...arr2]; - } -arr = [3, 5, 6, 2, 1, 7, 4]; -console.log(mergeSort(arr)); + + +process.stdin.on('end', function () { + buf.split('\n').forEach(function (line, lineIdx) { + if (lineIdx % 2 === 1) { + nums = getInputArgs(line); + mergeSort(nums, 0, nums.length - 1); + console.log(nums.join(' ')); + } + + }); +}); ``` ### **Go** @@ -87,53 +225,52 @@ package main import "fmt" -func merge(nums, temp []int, low, mid, high int) { - for i, j, k := low, mid+1, low; k <= high; k++ { - if j > high || nums[i] < nums[j] { - temp[k] = nums[i] +func mergeSort(nums []int, low, high int) { + if low >= high { + return + } + mid := (low + high) >> 1 + mergeSort(nums, low, mid) + mergeSort(nums, mid+1, high) + i, j := low, mid+1 + tmp := make([]int, 0) + for i <= mid && j <= high { + if nums[i] <= nums[j] { + tmp = append(tmp, nums[i]) i++ } else { - temp[k] = nums[j] + tmp = append(tmp, nums[j]) j++ } } - for i := low; i <= high; i++ { - nums[i] = temp[i] + for i <= mid { + tmp = append(tmp, nums[i]) + i++ + } + for j <= high { + tmp = append(tmp, nums[j]) + j++ + } + for i, j = low, 0; i <= high; i, j = i+1, j+1 { + nums[i] = tmp[j] } } -func _mergeSort(nums, temp []int, low, high int) { - if low >= high { - return +func main() { + var n int + fmt.Scanf("%d\n", &n) + nums := make([]int, n) + for i := 0; i < n; i++ { + fmt.Scanf("%d", &nums[i]) } - mid := low + (high-low)/2 - _mergeSort(nums, temp, low, mid) - _mergeSort(nums, temp, mid+1, high) - merge(nums, temp, low, mid, high) -} -func mergeSort(nums []int) { - n := len(nums) - temp := make([]int, n) - _mergeSort(nums, temp, 0, n-1) -} + mergeSort(nums, 0, n-1) -func main() { - nums := []int{1, 2, 7, 4, 5, 3} - mergeSort(nums) - fmt.Println(nums) + for _, v := range nums { + fmt.Printf("%d ", v) + } } ``` - -## 算法分析 - -空间复杂度 O(n),时间复杂度 O(nlogn)。 - -对于规模为 n 的问题,一共要进行 log(n) 次的切分,每一层的合并复杂度都是 O(n),所以整体时间复杂度为 O(nlogn)。 - -由于合并 n 个元素需要分配一个大小为 n 的额外数组,所以空间复杂度为 O(n)。 - -这是一种稳定的排序算法。 diff --git a/basic/sorting/QuickSort/README.md b/basic/sorting/QuickSort/README.md index e41fc92af803a..9b36ab69155db 100644 --- a/basic/sorting/QuickSort/README.md +++ b/basic/sorting/QuickSort/README.md @@ -40,7 +40,7 @@ 快速排序也采用了分治的思想:把原始的数组筛选成较小和较大的两个子数组,然后递归地排序两个子数组。 -快排模板: +快速排序模板: ```java void quickSort(int[] nums, int low, int high) { From 50c74c3f0e313b51fc7695769a181851cd9934a8 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Mon, 14 Jun 2021 22:17:49 +0800 Subject: [PATCH 3/4] feat: binary search algorithm and template --- README.md | 7 +- README_EN.md | 7 +- basic/README.md | 1 - basic/README_EN.md | 1 - .../BinarySearch-II/BinarySearch.java | 89 -------- basic/searching/BinarySearch-II/README.md | 129 ----------- .../searching/BinarySearch/BinarySearch.java | 64 ------ basic/searching/BinarySearch/Main.java | 40 ++++ basic/searching/BinarySearch/Main.py | 24 ++ basic/searching/BinarySearch/README.md | 207 +++++++++++------- basic/sorting/MergeSort/README.md | 70 +++--- basic/sorting/QuickSort/README.md | 52 ++--- basic/summary.md | 1 - 13 files changed, 259 insertions(+), 433 deletions(-) delete mode 100644 basic/searching/BinarySearch-II/BinarySearch.java delete mode 100644 basic/searching/BinarySearch-II/README.md delete mode 100644 basic/searching/BinarySearch/BinarySearch.java create mode 100644 basic/searching/BinarySearch/Main.java create mode 100644 basic/searching/BinarySearch/Main.py diff --git a/README.md b/README.md index 28be4e98f3583..1822e842573e6 100644 --- a/README.md +++ b/README.md @@ -37,14 +37,13 @@ - [冒泡排序](./basic/sorting/BubbleSort/README.md) - [插入排序](./basic/sorting/InsertionSort/README.md) - [选择排序](./basic/sorting/SelectionSort/README.md) -- [归并排序](./basic/sorting/MergeSort/README.md) -- [快速排序](./basic/sorting/QuickSort/README.md) +- [归并排序(算法模板)](./basic/sorting/MergeSort/README.md) +- [快速排序(算法模板)](./basic/sorting/QuickSort/README.md) - [希尔排序](./basic/sorting/ShellSort/README.md) ### 查找算法 -- [二分查找](./basic/searching/BinarySearch/README.md) -- [二分查找 II](./basic/searching/BinarySearch-II/README.md) +- [二分查找(算法模板)](./basic/searching/BinarySearch/README.md) ## 高频考题 diff --git a/README_EN.md b/README_EN.md index a5decbb67f2cf..ba351aacd4b98 100644 --- a/README_EN.md +++ b/README_EN.md @@ -37,14 +37,13 @@ Complete solutions to [LeetCode](https://leetcode-cn.com/problemset/all/), [LCOF - [Bubble Sort](./basic/sorting/BubbleSort/README.md) - [Insertion Sort](./basic/sorting/InsertionSort/README.md) - [Selection Sort](./basic/sorting/SelectionSort/README.md) -- [Merge Sort](./basic/sorting/MergeSort/README.md) -- [Quick Sort](./basic/sorting/QuickSort/README.md) +- [Merge Sort(Algorithm Template)](./basic/sorting/MergeSort/README.md) +- [Quick Sort(Algorithm Template)](./basic/sorting/QuickSort/README.md) - [Shell Sort](./basic/sorting/ShellSort/README.md) ### Searching -- [Binary Search](./basic/searching/BinarySearch/README.md) -- [Binary Search II](./basic/searching/BinarySearch-II/README.md) +- [Binary Search(Algorithm Template)](./basic/searching/BinarySearch/README.md) ## High Frequency Interview Questions diff --git a/basic/README.md b/basic/README.md index b2e12cc19f266..ba46eda8d4c25 100644 --- a/basic/README.md +++ b/basic/README.md @@ -11,4 +11,3 @@ ## 查找算法 - [二分查找](./searching/BinarySearch/README.md) -- [二分查找 II](./searching/BinarySearch-II/README.md) diff --git a/basic/README_EN.md b/basic/README_EN.md index d4db69b840819..c968bace873f3 100644 --- a/basic/README_EN.md +++ b/basic/README_EN.md @@ -12,4 +12,3 @@ ## Searching - [Binary Search](./searching/BinarySearch/README.md) -- [Binary Search II](./searching/BinarySearch-II/README.md) diff --git a/basic/searching/BinarySearch-II/BinarySearch.java b/basic/searching/BinarySearch-II/BinarySearch.java deleted file mode 100644 index 32979b4e9360e..0000000000000 --- a/basic/searching/BinarySearch-II/BinarySearch.java +++ /dev/null @@ -1,89 +0,0 @@ -public class BinarySearch { - - public static int search1(int[] nums, int val) { - int n = nums.length; - int low = 0, high = n - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] < val) { - low = mid + 1; - } else if (nums[mid] > val) { - high = mid - 1; - } else { - // 如果nums[mid]是第一个元素,或者nums[mid-1]不等于val - // 说明nums[mid]就是第一个值为给定值的元素 - if (mid == 0 || nums[mid - 1] != val) { - return mid; - } - high = mid - 1; - } - } - return -1; - } - - public static int search2(int[] nums, int val) { - int n = nums.length; - int low = 0, high = n - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] < val) { - low = mid + 1; - } else if (nums[mid] > val) { - high = mid - 1; - } else { - // 如果nums[mid]是最后一个元素,或者nums[mid+1]不等于val - // 说明nums[mid]就是最后一个值为给定值的元素 - if (mid == n - 1 || nums[mid + 1] != val) { - return mid; - } - low = mid + 1; - } - } - return -1; - } - - public static int search3(int[] nums, int val) { - int low = 0, high = nums.length - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] < val) { - low = mid + 1; - } else { - // 如果nums[mid]是第一个元素,或者nums[mid-1]小于val - // 说明nums[mid]就是第一个大于等于给定值的元素 - if (mid == 0 || nums[mid - 1] < val) { - return mid; - } - high = mid - 1; - } - } - return -1; - } - - public static int search4(int[] nums, int val) { - int n = nums.length; - int low = 0, high = n - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] > val) { - high = mid - 1; - } else { - // 如果nums[mid]是最后一个元素,或者nums[mid+1]大于val - // 说明nums[mid]就是最后一个小于等于给定值的元素 - if (mid == n - 1 || nums[mid + 1] > val) { - return mid; - } - low = mid + 1; - } - } - return -1; - } - - public static void main(String[] args) { - int[] nums = {1, 2, 2, 2, 2, 8, 9}; - System.out.println(search1(nums, 2)); // 1 - System.out.println(search2(nums, 2)); // 4 - System.out.println(search3(nums, 2)); // 1 - System.out.println(search4(nums, 2)); // 4 - } -} diff --git a/basic/searching/BinarySearch-II/README.md b/basic/searching/BinarySearch-II/README.md deleted file mode 100644 index c9648732d34a9..0000000000000 --- a/basic/searching/BinarySearch-II/README.md +++ /dev/null @@ -1,129 +0,0 @@ -# 二分查找 II - -前面讲的二分查找算法,是最为简单的一种,在不存在重复元素的有序数组中,查找值等于给定值的元素。 - -接下来,我们来看看二分查找算法四种常见的变形问题,分别是: - -1. 查找第一个值等于给定值的元素 -1. 查找最后一个值等于给定值的元素 -1. 查找第一个大于等于给定值的元素 -1. 查找最后一个小于等于给定值的元素 - -## 1. 查找第一个值等于给定值的元素 - - - -### **Java** - -```java -public static int search(int[] nums, int val) { - int n = nums.length; - int low = 0, high = n - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] < val) { - low = mid + 1; - } else if (nums[mid] > val) { - high = mid - 1; - } else { - // 如果nums[mid]是第一个元素,或者nums[mid-1]不等于val - // 说明nums[mid]就是第一个值为给定值的元素 - if (mid == 0 || nums[mid - 1] != val) { - return mid; - } - high = mid - 1; - } - } - return -1; -} -``` - - - -## 2. 查找最后一个值等于给定值的元素 - - - -### **Java** - -```java -public static int search(int[] nums, int val) { - int n = nums.length; - int low = 0, high = n - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] < val) { - low = mid + 1; - } else if (nums[mid] > val) { - high = mid - 1; - } else { - // 如果nums[mid]是最后一个元素,或者nums[mid+1]不等于val - // 说明nums[mid]就是最后一个值为给定值的元素 - if (mid == n - 1 || nums[mid + 1] != val) { - return mid; - } - low = mid + 1; - } - } - return -1; -} -``` - - - -## 3. 查找第一个大于等于给定值的元素 - - - -### **Java** - -```java -public static int search(int[] nums, int val) { - int low = 0, high = nums.length - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] < val) { - low = mid + 1; - } else { - // 如果nums[mid]是第一个元素,或者nums[mid-1]小于val - // 说明nums[mid]就是第一个大于等于给定值的元素 - if (mid == 0 || nums[mid - 1] < val) { - return mid; - } - high = mid - 1; - } - } - return -1; -} -``` - - - -## 4. 查找最后一个小于等于给定值的元素 - - - -### **Java** - -```java -public static int search(int[] nums, int val) { - int n = nums.length; - int low = 0, high = n - 1; - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] > val) { - high = mid - 1; - } else { - // 如果nums[mid]是最后一个元素,或者nums[mid+1]大于val - // 说明nums[mid]就是最后一个小于等于给定值的元素 - if (mid == n - 1 || nums[mid + 1] > val) { - return mid; - } - low = mid + 1; - } - } - return -1; -} -``` - - diff --git a/basic/searching/BinarySearch/BinarySearch.java b/basic/searching/BinarySearch/BinarySearch.java deleted file mode 100644 index ee97fc4414ea3..0000000000000 --- a/basic/searching/BinarySearch/BinarySearch.java +++ /dev/null @@ -1,64 +0,0 @@ -public class BinarySearch { - - private static int search(int[] nums, int low, int high, int val) { - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] == val) { - return mid; - } else if (nums[mid] < val) { - low = mid + 1; - } else { - high = mid - 1; - } - } - return -1; - } - - private static int searchRecursive(int[] nums, int low, int high, int val) { - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] == val) { - return mid; - } else if (nums[mid] < val) { - return searchRecursive(nums, mid + 1, high, val); - } else { - return searchRecursive(nums, low, mid - 1, val); - } - } - return -1; - } - - /** - * 二分查找(非递归) - * - * @param nums 有序数组 - * @param val 要查找的值 - * @return 要查找的值在数组中的索引位置 - */ - private static int search(int[] nums, int val) { - return search(nums, 0, nums.length - 1, val); - } - - /** - * 二分查找(递归) - * - * @param nums 有序数组 - * @param val 要查找的值 - * @return 要查找的值在数组中的索引位置 - */ - private static int searchRecursive(int[] nums, int val) { - return searchRecursive(nums, 0, nums.length - 1, val); - } - - public static void main(String[] args) { - int[] nums = {1, 2, 5, 7, 8, 9}; - - // 非递归查找 - int r1 = search(nums, 7); - System.out.println(r1); - - // 递归查找 - int r2 = search(nums, 7); - System.out.println(r2); - } -} \ No newline at end of file diff --git a/basic/searching/BinarySearch/Main.java b/basic/searching/BinarySearch/Main.java new file mode 100644 index 0000000000000..ddb21737baf72 --- /dev/null +++ b/basic/searching/BinarySearch/Main.java @@ -0,0 +1,40 @@ +import java.util.Scanner; + +public class Main { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(), q = sc.nextInt(); + int[] nums = new int[n]; + for (int i = 0; i < n; ++i) { + nums[i] = sc.nextInt(); + } + while (q-- > 0) { + int x = sc.nextInt(); + int low = 0, high = n - 1; + while (low < high) { + int mid = (low + high) >> 1; + if (nums[mid] >= x) { + high = mid; + } else { + low = mid + 1; + } + } + if (nums[low] != x) { + System.out.println("-1 -1"); + } else { + int t = low; + low = 0; + high = n - 1; + while (low < high) { + int mid = (low + high + 1) >> 1; + if (nums[mid] <= x) { + low = mid; + } else { + high = mid - 1; + } + } + System.out.printf("%d %d\n", t, low); + } + } + } +} \ No newline at end of file diff --git a/basic/searching/BinarySearch/Main.py b/basic/searching/BinarySearch/Main.py new file mode 100644 index 0000000000000..68eb1d71fd51d --- /dev/null +++ b/basic/searching/BinarySearch/Main.py @@ -0,0 +1,24 @@ +n, q = map(int, input().split()) +nums = list(map(int, input().split())) + +for _ in range(q): + x = int(input()) + low, high = 0, n - 1 + while low < high: + mid = (low + high) >> 1 + if nums[mid] >= x: + high = mid + else: + low = mid + 1 + if nums[low] != x: + print('-1 -1') + else: + t = low + low, high = 0, n - 1 + while low < high: + mid = (low + high + 1) >> 1 + if nums[mid] <= x: + low = mid + else: + high = mid - 1 + print(f'{t} {low}') diff --git a/basic/searching/BinarySearch/README.md b/basic/searching/BinarySearch/README.md index df647bc081d64..f9055e9d83f01 100644 --- a/basic/searching/BinarySearch/README.md +++ b/basic/searching/BinarySearch/README.md @@ -1,107 +1,156 @@ # 二分查找 -二分查找是一种非常高效的查找算法,高效到什么程度呢?我们来分析一下它的时间复杂度。 +二分的本质并非“单调性”,而是“边界”,只要找到某种性质,使得整个区间一分为二,那么就可以用二分把边界点二分出来。 -假设数据大小是 n,每次查找后数据都会缩小为原来的一半,也就是会除以 2。最坏情况下,直到查找区间被缩小为空,才停止。 +整数二分算法模板: -被查找区间的大小变化为: +```java +/** 检查x是否满足某种性质 */ +boolean check(int x) {} + +/** 区间[low, high]被划分成[low, mid]和[mid + 1, high]时使用 */ +int binarySearch1(int low, int high) { + while (low < high) { + int mid = (low + high) >> 1; + if (check(mid)) high = mid; + else low = mid + 1; + } + return low; +} -``` -n, n/2, n/4, n/8, ..., n/(2^k) +/** 区间[low, high] 被划分成[low, mid - 1]和[mid, high]时使用 */ +int binarySearch2(int low, int high) { + while (low < high) { + int mid = (low + high + 1) >> 1; + if (check(mid)) low = mid; + else high = mid - 1; + } + return low; +} ``` -可以看出来,这是一个等比数列。其中 `n/(2^k)=1` 时,k 的值就是总共缩小的次数。而每一次缩小操作只涉及两个数据的大小比较,所以,经过了 k 次区间缩小操作,时间复杂度就是 O(k)。通过 `n/(2^k)=1`,我们可以求得 `k=log2n`,所以时间复杂度就是 O(logn)。 +## 题目描述 -## 代码示例 +给定一个按照升序排列的长度为 `n` 的整数数组,以及 `q` 个查询。 -注意容易出错的 3 个地方。 +对于每个查询,返回一个元素 k 的起始位置和终止位置(位置从 0 开始计数)。 -1. 循环退出条件是 `low <= high`,而不是 `low < high`; -1. mid 的取值,可以是 `mid = (low + high) / 2`,但是如果 low 和 high 比较大的话,`low + high` 可能会溢出,所以这里写为 `mid = (low + high) >>> 1`; -1. low 和 high 的更新分别为 `low = mid + 1`、`high = mid - 1`。 +如果数组中不存在该元素,则返回 `-1 -1`。 - +**输入格式** -### **Java** +第一行包含整数 n 和 q,表示数组长度和询问个数。 -非递归实现: +第二行包含 n 个整数(均在 1∼10000 范围内),表示完整数组。 -```java -public class BinarySearch { - - private static int search(int[] nums, int low, int high, int val) { - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] == val) { - return mid; - } else if (nums[mid] < val) { - low = mid + 1; - } else { - high = mid - 1; - } - } - return -1; - } +接下来 q 行,每行包含一个整数 k,表示一个询问元素。 - /** - * 二分查找(非递归) - * - * @param nums 有序数组 - * @param val 要查找的值 - * @return 要查找的值在数组中的索引位置 - */ - private static int search(int[] nums, int val) { - return search(nums, 0, nums.length - 1, val); - } +**输出格式** - public static void main(String[] args) { - int[] nums = {1, 2, 5, 7, 8, 9}; +共 q 行,每行包含两个整数,表示所求元素的起始位置和终止位置。 + +如果数组中不存在该元素,则返回 `-1 -1`。 + +**数据范围** + +- 1≤n≤100000 +- 1≤q≤10000 +- 1≤k≤10000 + +**输入样例:** - // 非递归查找 - int r1 = search(nums, 7); - System.out.println(r1); - } -} ``` +6 3 +1 2 2 3 3 4 +3 +4 +5 +``` + +**输出样例:** + +``` +3 4 +5 5 +-1 -1 +``` + +## 代码实现 -递归实现: + + +### **Python3** + +```python +n, q = map(int, input().split()) +nums = list(map(int, input().split())) + +for _ in range(q): + x = int(input()) + low, high = 0, n - 1 + while low < high: + mid = (low + high) >> 1 + if nums[mid] >= x: + high = mid + else: + low = mid + 1 + if nums[low] != x: + print('-1 -1') + else: + t = low + low, high = 0, n - 1 + while low < high: + mid = (low + high + 1) >> 1 + if nums[mid] <= x: + low = mid + else: + high = mid - 1 + print(f'{t} {low}') +``` + +### **Java** ```java -public class BinarySearch { - - private static int searchRecursive(int[] nums, int low, int high, int val) { - while (low <= high) { - int mid = (low + high) >>> 1; - if (nums[mid] == val) { - return mid; - } else if (nums[mid] < val) { - return searchRecursive(nums, mid + 1, high, val); +import java.util.Scanner; + +public class Main { + public static void main(String[] args) { + Scanner sc = new Scanner(System.in); + int n = sc.nextInt(), q = sc.nextInt(); + int[] nums = new int[n]; + for (int i = 0; i < n; ++i) { + nums[i] = sc.nextInt(); + } + while (q-- > 0) { + int x = sc.nextInt(); + int low = 0, high = n - 1; + while (low < high) { + int mid = (low + high) >> 1; + if (nums[mid] >= x) { + high = mid; + } else { + low = mid + 1; + } + } + if (nums[low] != x) { + System.out.println("-1 -1"); } else { - return searchRecursive(nums, low, mid - 1, val); + int t = low; + low = 0; + high = n - 1; + while (low < high) { + int mid = (low + high + 1) >> 1; + if (nums[mid] <= x) { + low = mid; + } else { + high = mid - 1; + } + } + System.out.printf("%d %d\n", t, low); } } - return -1; - } - - /** - * 二分查找(递归) - * - * @param nums 有序数组 - * @param val 要查找的值 - * @return 要查找的值在数组中的索引位置 - */ - private static int searchRecursive(int[] nums, int val) { - return searchRecursive(nums, 0, nums.length - 1, val); - } - - public static void main(String[] args) { - int[] nums = {1, 2, 5, 7, 8, 9}; - - // 递归查找 - int r2 = searchRecursive(nums, 7); - System.out.println(r2); } } ``` - + \ No newline at end of file diff --git a/basic/sorting/MergeSort/README.md b/basic/sorting/MergeSort/README.md index 0a5af8c580317..0928e6562a9b4 100644 --- a/basic/sorting/MergeSort/README.md +++ b/basic/sorting/MergeSort/README.md @@ -1,5 +1,39 @@ # 归并排序 +归并排序的核心思想是分治,把一个复杂问题拆分成若干个子问题来求解。 + +归并排序的算法思想是:把数组从中间划分为两个子数组,一直递归地把子数组划分成更小的数组,直到子数组里面只有一个元素的时候开始排序。排序的方法就是按照大小顺序合并两个元素。接着依次按照递归的顺序返回,不断合并排好序的数组,直到把整个数组排好序。 + +**归并排序算法模板:** + +```java +void mergeSort(int[] nums, int low, int high) { + if (low >= high) { + return; + } + int mid = (low + high) >>> 1; + mergeSort(nums, low, mid); + mergeSort(nums, mid + 1, high); + int i = low, j = mid + 1, k = 0; + while (i <= mid && j <= high) { + if (nums[i] <= nums[j]) { + tmp[k++] = nums[i++]; + } else { + tmp[k++] = nums[j++]; + } + } + while (i <= mid) { + tmp[k++] = nums[i++]; + } + while (j <= high) { + tmp[k++] = nums[j++]; + } + for (i = low, j = 0; i <= high; ++i, ++j) { + nums[i] = tmp[j]; + } +} +``` + ## 题目描述 给定你一个长度为 `n` 的整数数列。 @@ -35,41 +69,7 @@ 1 2 3 4 5 ``` -## 解法 - -归并排序的核心思想是分治,把一个复杂问题拆分成若干个子问题来求解。 - -归并排序的算法思想是:把数组从中间划分为两个子数组,一直递归地把子数组划分成更小的数组,直到子数组里面只有一个元素的时候开始排序。排序的方法就是按照大小顺序合并两个元素。接着依次按照递归的顺序返回,不断合并排好序的数组,直到把整个数组排好序。 - -归并排序模板: - -```java -void mergeSort(int[] nums, int low, int high) { - if (low >= high) { - return; - } - int mid = (low + high) >>> 1; - mergeSort(nums, low, mid); - mergeSort(nums, mid + 1, high); - int i = low, j = mid + 1, k = 0; - while (i <= mid && j <= high) { - if (nums[i] <= nums[j]) { - tmp[k++] = nums[i++]; - } else { - tmp[k++] = nums[j++]; - } - } - while (i <= mid) { - tmp[k++] = nums[i++]; - } - while (j <= high) { - tmp[k++] = nums[j++]; - } - for (i = low, j = 0; i <= high; ++i, ++j) { - nums[i] = tmp[j]; - } -} -``` +## 代码实现 diff --git a/basic/sorting/QuickSort/README.md b/basic/sorting/QuickSort/README.md index 9b36ab69155db..57b5d769126d0 100644 --- a/basic/sorting/QuickSort/README.md +++ b/basic/sorting/QuickSort/README.md @@ -1,5 +1,30 @@ # 快速排序 +快速排序也采用了分治的思想:把原始的数组筛选成较小和较大的两个子数组,然后递归地排序两个子数组。 + +**快速排序算法模板:** + +```java +void quickSort(int[] nums, int low, int high) { + if (low >= high) { + return; + } + int i = low - 1, j = high + 1; + int x = nums[low]; + while (i < j) { + while (nums[++i] < x); + while (nums[--j] > x); + if (i < j) { + int t = nums[i]; + nums[i] = nums[j]; + nums[j] = t; + } + } + quickSort(nums, low, j); + quickSort(nums, j + 1, high); +} +``` + ## 题目描述 给定你一个长度为 `n` 的整数数列。 @@ -36,32 +61,7 @@ ``` -## 解法 - -快速排序也采用了分治的思想:把原始的数组筛选成较小和较大的两个子数组,然后递归地排序两个子数组。 - -快速排序模板: - -```java -void quickSort(int[] nums, int low, int high) { - if (low >= high) { - return; - } - int i = low - 1, j = high + 1; - int x = nums[low]; - while (i < j) { - while (nums[++i] < x); - while (nums[--j] > x); - if (i < j) { - int t = nums[i]; - nums[i] = nums[j]; - nums[j] = t; - } - } - quickSort(nums, low, j); - quickSort(nums, j + 1, high); -} -``` +## 代码实现 diff --git a/basic/summary.md b/basic/summary.md index 4b5389628c744..cb496af06e5bc 100644 --- a/basic/summary.md +++ b/basic/summary.md @@ -7,4 +7,3 @@ - [快速排序](/basic/sorting/QuickSort/README.md) - 查找算法 - [二分查找](/basic/searching/BinarySearch/README.md) - - [二分查找 II](/basic/searching/BinarySearch-II/README.md) From 2b59276c3ea7120c540e7666958d846cd56c134b Mon Sep 17 00:00:00 2001 From: yanglbme Date: Wed, 16 Jun 2021 08:25:43 +0800 Subject: [PATCH 4/4] chore: rename variables --- basic/searching/BinarySearch/Main.java | 28 ++++---- basic/searching/BinarySearch/Main.py | 26 ++++---- basic/searching/BinarySearch/README.md | 82 +++++++++++------------ basic/sorting/MergeSort/Main.go | 18 +++--- basic/sorting/MergeSort/Main.java | 18 +++--- basic/sorting/MergeSort/Main.js | 18 +++--- basic/sorting/MergeSort/Main.py | 18 +++--- basic/sorting/MergeSort/README.md | 90 +++++++++++++------------- basic/sorting/QuickSort/Main.go | 12 ++-- basic/sorting/QuickSort/Main.java | 10 +-- basic/sorting/QuickSort/Main.js | 10 +-- basic/sorting/QuickSort/Main.py | 10 +-- basic/sorting/QuickSort/README.md | 50 +++++++------- 13 files changed, 195 insertions(+), 195 deletions(-) diff --git a/basic/searching/BinarySearch/Main.java b/basic/searching/BinarySearch/Main.java index ddb21737baf72..a2b28718f4bda 100644 --- a/basic/searching/BinarySearch/Main.java +++ b/basic/searching/BinarySearch/Main.java @@ -10,30 +10,30 @@ public static void main(String[] args) { } while (q-- > 0) { int x = sc.nextInt(); - int low = 0, high = n - 1; - while (low < high) { - int mid = (low + high) >> 1; + int left = 0, right = n - 1; + while (left < right) { + int mid = (left + right) >> 1; if (nums[mid] >= x) { - high = mid; + right = mid; } else { - low = mid + 1; + left = mid + 1; } } - if (nums[low] != x) { + if (nums[left] != x) { System.out.println("-1 -1"); } else { - int t = low; - low = 0; - high = n - 1; - while (low < high) { - int mid = (low + high + 1) >> 1; + int t = left; + left = 0; + right = n - 1; + while (left < right) { + int mid = (left + right + 1) >> 1; if (nums[mid] <= x) { - low = mid; + left = mid; } else { - high = mid - 1; + right = mid - 1; } } - System.out.printf("%d %d\n", t, low); + System.out.printf("%d %d\n", t, left); } } } diff --git a/basic/searching/BinarySearch/Main.py b/basic/searching/BinarySearch/Main.py index 68eb1d71fd51d..5cc5b8fcf8f82 100644 --- a/basic/searching/BinarySearch/Main.py +++ b/basic/searching/BinarySearch/Main.py @@ -3,22 +3,22 @@ for _ in range(q): x = int(input()) - low, high = 0, n - 1 - while low < high: - mid = (low + high) >> 1 + left, right = 0, n - 1 + while left < right: + mid = (left + right) >> 1 if nums[mid] >= x: - high = mid + right = mid else: - low = mid + 1 - if nums[low] != x: + left = mid + 1 + if nums[left] != x: print('-1 -1') else: - t = low - low, high = 0, n - 1 - while low < high: - mid = (low + high + 1) >> 1 + t = left + left, right = 0, n - 1 + while left < right: + mid = (left + right + 1) >> 1 if nums[mid] <= x: - low = mid + left = mid else: - high = mid - 1 - print(f'{t} {low}') + right = mid - 1 + print(f'{t} {left}') diff --git a/basic/searching/BinarySearch/README.md b/basic/searching/BinarySearch/README.md index f9055e9d83f01..3e0aad13c06b3 100644 --- a/basic/searching/BinarySearch/README.md +++ b/basic/searching/BinarySearch/README.md @@ -8,24 +8,24 @@ /** 检查x是否满足某种性质 */ boolean check(int x) {} -/** 区间[low, high]被划分成[low, mid]和[mid + 1, high]时使用 */ -int binarySearch1(int low, int high) { - while (low < high) { - int mid = (low + high) >> 1; - if (check(mid)) high = mid; - else low = mid + 1; +/** 区间[left, right]被划分成[left, mid]和[mid + 1, right]时使用 */ +int binarySearch1(int left, int right) { + while (left < right) { + int mid = (left + right) >> 1; + if (check(mid)) right = mid; + else left = mid + 1; } - return low; + return left; } -/** 区间[low, high] 被划分成[low, mid - 1]和[mid, high]时使用 */ -int binarySearch2(int low, int high) { - while (low < high) { - int mid = (low + high + 1) >> 1; - if (check(mid)) low = mid; - else high = mid - 1; +/** 区间[left, right] 被划分成[left, mid - 1]和[mid, right]时使用 */ +int binarySearch2(int left, int right) { + while (left < right) { + int mid = (left + right + 1) >> 1; + if (check(mid)) left = mid; + else right = mid - 1; } - return low; + return left; } ``` @@ -87,25 +87,25 @@ nums = list(map(int, input().split())) for _ in range(q): x = int(input()) - low, high = 0, n - 1 - while low < high: - mid = (low + high) >> 1 + left, right = 0, n - 1 + while left < right: + mid = (left + right) >> 1 if nums[mid] >= x: - high = mid + right = mid else: - low = mid + 1 - if nums[low] != x: + left = mid + 1 + if nums[left] != x: print('-1 -1') else: - t = low - low, high = 0, n - 1 - while low < high: - mid = (low + high + 1) >> 1 + t = left + left, right = 0, n - 1 + while left < right: + mid = (left + right + 1) >> 1 if nums[mid] <= x: - low = mid + left = mid else: - high = mid - 1 - print(f'{t} {low}') + right = mid - 1 + print(f'{t} {left}') ``` ### **Java** @@ -123,30 +123,30 @@ public class Main { } while (q-- > 0) { int x = sc.nextInt(); - int low = 0, high = n - 1; - while (low < high) { - int mid = (low + high) >> 1; + int left = 0, right = n - 1; + while (left < right) { + int mid = (left + right) >> 1; if (nums[mid] >= x) { - high = mid; + right = mid; } else { - low = mid + 1; + left = mid + 1; } } - if (nums[low] != x) { + if (nums[left] != x) { System.out.println("-1 -1"); } else { - int t = low; - low = 0; - high = n - 1; - while (low < high) { - int mid = (low + high + 1) >> 1; + int t = left; + left = 0; + right = n - 1; + while (left < right) { + int mid = (left + right + 1) >> 1; if (nums[mid] <= x) { - low = mid; + left = mid; } else { - high = mid - 1; + right = mid - 1; } } - System.out.printf("%d %d\n", t, low); + System.out.printf("%d %d\n", t, left); } } } diff --git a/basic/sorting/MergeSort/Main.go b/basic/sorting/MergeSort/Main.go index 33c6941c0dfd9..931f15916cb2b 100644 --- a/basic/sorting/MergeSort/Main.go +++ b/basic/sorting/MergeSort/Main.go @@ -2,16 +2,16 @@ package main import "fmt" -func mergeSort(nums []int, low, high int) { - if low >= high { +func mergeSort(nums []int, left, right int) { + if left >= right { return } - mid := (low + high) >> 1 - mergeSort(nums, low, mid) - mergeSort(nums, mid+1, high) - i, j := low, mid+1 + mid := (left + right) >> 1 + mergeSort(nums, left, mid) + mergeSort(nums, mid+1, right) + i, j := left, mid+1 tmp := make([]int, 0) - for i <= mid && j <= high { + for i <= mid && j <= right { if nums[i] <= nums[j] { tmp = append(tmp, nums[i]) i++ @@ -24,11 +24,11 @@ func mergeSort(nums []int, low, high int) { tmp = append(tmp, nums[i]) i++ } - for j <= high { + for j <= right { tmp = append(tmp, nums[j]) j++ } - for i, j = low, 0; i <= high; i, j = i+1, j+1 { + for i, j = left, 0; i <= right; i, j = i+1, j+1 { nums[i] = tmp[j] } } diff --git a/basic/sorting/MergeSort/Main.java b/basic/sorting/MergeSort/Main.java index 0775465b6cc10..6e23dd1992b56 100644 --- a/basic/sorting/MergeSort/Main.java +++ b/basic/sorting/MergeSort/Main.java @@ -16,15 +16,15 @@ public static void main(String[] args) { } } - public static void mergeSort(int[] nums, int low, int high) { - if (low >= high) { + public static void mergeSort(int[] nums, int left, int right) { + if (left >= right) { return; } - int mid = (low + high) >>> 1; - mergeSort(nums, low, mid); - mergeSort(nums, mid + 1, high); - int i = low, j = mid + 1, k = 0; - while (i <= mid && j <= high) { + int mid = (left + right) >>> 1; + mergeSort(nums, left, mid); + mergeSort(nums, mid + 1, right); + int i = left, j = mid + 1, k = 0; + while (i <= mid && j <= right) { if (nums[i] <= nums[j]) { tmp[k++] = nums[i++]; } else { @@ -34,10 +34,10 @@ public static void mergeSort(int[] nums, int low, int high) { while (i <= mid) { tmp[k++] = nums[i++]; } - while (j <= high) { + while (j <= right) { tmp[k++] = nums[j++]; } - for (i = low, j = 0; i <= high; ++i, ++j) { + for (i = left, j = 0; i <= right; ++i, ++j) { nums[i] = tmp[j]; } } diff --git a/basic/sorting/MergeSort/Main.js b/basic/sorting/MergeSort/Main.js index e311d66d7b47a..7d4a46a4d0966 100644 --- a/basic/sorting/MergeSort/Main.js +++ b/basic/sorting/MergeSort/Main.js @@ -9,18 +9,18 @@ let getInputArgs = line => { return line.split(' ').filter(s => s !== '').map(x => parseInt(x)); } -function mergeSort(nums, low, high) { - if (low >= high) { +function mergeSort(nums, left, right) { + if (left >= right) { return; } - const mid = (low + high) >> 1; - mergeSort(nums, low, mid); - mergeSort(nums, mid + 1, high); - let i = low; + const mid = (left + right) >> 1; + mergeSort(nums, left, mid); + mergeSort(nums, mid + 1, right); + let i = left; let j = mid + 1; let tmp = []; - while (i <= mid && j <= high) { + while (i <= mid && j <= right) { if (nums[i] <= nums[j]) { tmp.push(nums[i++]); } else { @@ -30,10 +30,10 @@ function mergeSort(nums, low, high) { while (i <= mid) { tmp.push(nums[i++]); } - while (j <= high) { + while (j <= right) { tmp.push(nums[j++]); } - for (i = low, j = 0; i <= high; ++i, ++j) { + for (i = left, j = 0; i <= right; ++i, ++j) { nums[i] = tmp[j]; } } diff --git a/basic/sorting/MergeSort/Main.py b/basic/sorting/MergeSort/Main.py index 30c9bab4358e9..9d72ff27bc187 100644 --- a/basic/sorting/MergeSort/Main.py +++ b/basic/sorting/MergeSort/Main.py @@ -2,15 +2,15 @@ nums = list(map(int, input().split())) -def merge_sort(nums, low, high): - if low >= high: +def merge_sort(nums, left, right): + if left >= right: return - mid = (low + high) >> 1 - merge_sort(nums, low, mid) - merge_sort(nums, mid + 1, high) + mid = (left + right) >> 1 + merge_sort(nums, left, mid) + merge_sort(nums, mid + 1, right) tmp = [] - i, j = low, mid + 1 - while i <= mid and j <= high: + i, j = left, mid + 1 + while i <= mid and j <= right: if nums[i] <= nums[j]: tmp.append(nums[i]) i += 1 @@ -20,12 +20,12 @@ def merge_sort(nums, low, high): while i <= mid: tmp.append(nums[i]) i += 1 - while j <= high: + while j <= right: tmp.append(nums[j]) j += 1 j = 0 - for i in range(low, high + 1): + for i in range(left, right + 1): nums[i] = tmp[j] j += 1 diff --git a/basic/sorting/MergeSort/README.md b/basic/sorting/MergeSort/README.md index 0928e6562a9b4..e6d35071d80b1 100644 --- a/basic/sorting/MergeSort/README.md +++ b/basic/sorting/MergeSort/README.md @@ -7,15 +7,15 @@ **归并排序算法模板:** ```java -void mergeSort(int[] nums, int low, int high) { - if (low >= high) { +void mergeSort(int[] nums, int left, int right) { + if (left >= right) { return; } - int mid = (low + high) >>> 1; - mergeSort(nums, low, mid); - mergeSort(nums, mid + 1, high); - int i = low, j = mid + 1, k = 0; - while (i <= mid && j <= high) { + int mid = (left + right) >>> 1; + mergeSort(nums, left, mid); + mergeSort(nums, mid + 1, right); + int i = left, j = mid + 1, k = 0; + while (i <= mid && j <= right) { if (nums[i] <= nums[j]) { tmp[k++] = nums[i++]; } else { @@ -25,10 +25,10 @@ void mergeSort(int[] nums, int low, int high) { while (i <= mid) { tmp[k++] = nums[i++]; } - while (j <= high) { + while (j <= right) { tmp[k++] = nums[j++]; } - for (i = low, j = 0; i <= high; ++i, ++j) { + for (i = left, j = 0; i <= right; ++i, ++j) { nums[i] = tmp[j]; } } @@ -80,15 +80,15 @@ N = int(input()) nums = list(map(int, input().split())) -def merge_sort(nums, low, high): - if low >= high: +def merge_sort(nums, left, right): + if left >= right: return - mid = (low + high) >> 1 - merge_sort(nums, low, mid) - merge_sort(nums, mid + 1, high) + mid = (left + right) >> 1 + merge_sort(nums, left, mid) + merge_sort(nums, mid + 1, right) tmp = [] - i, j = low, mid + 1 - while i <= mid and j <= high: + i, j = left, mid + 1 + while i <= mid and j <= right: if nums[i] <= nums[j]: tmp.append(nums[i]) i += 1 @@ -98,12 +98,12 @@ def merge_sort(nums, low, high): while i <= mid: tmp.append(nums[i]) i += 1 - while j <= high: + while j <= right: tmp.append(nums[j]) j += 1 j = 0 - for i in range(low, high + 1): + for i in range(left, right + 1): nums[i] = tmp[j] j += 1 @@ -133,15 +133,15 @@ public class Main { } } - public static void mergeSort(int[] nums, int low, int high) { - if (low >= high) { + public static void mergeSort(int[] nums, int left, int right) { + if (left >= right) { return; } - int mid = (low + high) >>> 1; - mergeSort(nums, low, mid); - mergeSort(nums, mid + 1, high); - int i = low, j = mid + 1, k = 0; - while (i <= mid && j <= high) { + int mid = (left + right) >>> 1; + mergeSort(nums, left, mid); + mergeSort(nums, mid + 1, right); + int i = left, j = mid + 1, k = 0; + while (i <= mid && j <= right) { if (nums[i] <= nums[j]) { tmp[k++] = nums[i++]; } else { @@ -151,10 +151,10 @@ public class Main { while (i <= mid) { tmp[k++] = nums[i++]; } - while (j <= high) { + while (j <= right) { tmp[k++] = nums[j++]; } - for (i = low, j = 0; i <= high; ++i, ++j) { + for (i = left, j = 0; i <= right; ++i, ++j) { nums[i] = tmp[j]; } } @@ -175,18 +175,18 @@ let getInputArgs = line => { return line.split(' ').filter(s => s !== '').map(x => parseInt(x)); } -function mergeSort(nums, low, high) { - if (low >= high) { +function mergeSort(nums, left, right) { + if (left >= right) { return; } - const mid = (low + high) >> 1; - mergeSort(nums, low, mid); - mergeSort(nums, mid + 1, high); - let i = low; + const mid = (left + right) >> 1; + mergeSort(nums, left, mid); + mergeSort(nums, mid + 1, right); + let i = left; let j = mid + 1; let tmp = []; - while (i <= mid && j <= high) { + while (i <= mid && j <= right) { if (nums[i] <= nums[j]) { tmp.push(nums[i++]); } else { @@ -196,10 +196,10 @@ function mergeSort(nums, low, high) { while (i <= mid) { tmp.push(nums[i++]); } - while (j <= high) { + while (j <= right) { tmp.push(nums[j++]); } - for (i = low, j = 0; i <= high; ++i, ++j) { + for (i = left, j = 0; i <= right; ++i, ++j) { nums[i] = tmp[j]; } } @@ -225,16 +225,16 @@ package main import "fmt" -func mergeSort(nums []int, low, high int) { - if low >= high { +func mergeSort(nums []int, left, right int) { + if left >= right { return } - mid := (low + high) >> 1 - mergeSort(nums, low, mid) - mergeSort(nums, mid+1, high) - i, j := low, mid+1 + mid := (left + right) >> 1 + mergeSort(nums, left, mid) + mergeSort(nums, mid+1, right) + i, j := left, mid+1 tmp := make([]int, 0) - for i <= mid && j <= high { + for i <= mid && j <= right { if nums[i] <= nums[j] { tmp = append(tmp, nums[i]) i++ @@ -247,11 +247,11 @@ func mergeSort(nums []int, low, high int) { tmp = append(tmp, nums[i]) i++ } - for j <= high { + for j <= right { tmp = append(tmp, nums[j]) j++ } - for i, j = low, 0; i <= high; i, j = i+1, j+1 { + for i, j = left, 0; i <= right; i, j = i+1, j+1 { nums[i] = tmp[j] } } diff --git a/basic/sorting/QuickSort/Main.go b/basic/sorting/QuickSort/Main.go index 60f144e799932..b72d6dfeabb46 100644 --- a/basic/sorting/QuickSort/Main.go +++ b/basic/sorting/QuickSort/Main.go @@ -2,12 +2,12 @@ package main import "fmt" -func quickSort(nums []int, low, high int) { - if low >= high { +func quickSort(nums []int, left, right int) { + if left >= right { return } - i, j := low-1, high+1 - x := nums[(low+high)>>1] + i, j := left-1, right+1 + x := nums[(left+right)>>1] for i < j { for { i++ @@ -25,8 +25,8 @@ func quickSort(nums []int, low, high int) { nums[i], nums[j] = nums[j], nums[i] } } - quickSort(nums, low, j) - quickSort(nums, j+1, high) + quickSort(nums, left, j) + quickSort(nums, j+1, right) } func main() { diff --git a/basic/sorting/QuickSort/Main.java b/basic/sorting/QuickSort/Main.java index 7d25358ebdf1c..395c88bef04ee 100644 --- a/basic/sorting/QuickSort/Main.java +++ b/basic/sorting/QuickSort/Main.java @@ -14,12 +14,12 @@ public static void main(String[] args) { } } - public static void quickSort(int[] nums, int low, int high) { - if (low >= high) { + public static void quickSort(int[] nums, int left, int high) { + if (left >= high) { return; } - int i = low - 1, j = high + 1; - int x = nums[low]; + int i = left - 1, j = high + 1; + int x = nums[left]; while (i < j) { while (nums[++i] < x); while (nums[--j] > x); @@ -29,7 +29,7 @@ public static void quickSort(int[] nums, int low, int high) { nums[j] = t; } } - quickSort(nums, low, j); + quickSort(nums, left, j); quickSort(nums, j + 1, high); } } \ No newline at end of file diff --git a/basic/sorting/QuickSort/Main.js b/basic/sorting/QuickSort/Main.js index 84d1d48c6d343..e01aaedc3d450 100644 --- a/basic/sorting/QuickSort/Main.js +++ b/basic/sorting/QuickSort/Main.js @@ -9,14 +9,14 @@ let getInputArgs = line => { return line.split(' ').filter(s => s !== '').map(x => parseInt(x)); } -function quickSort(nums, low, high) { - if (low >= high) { +function quickSort(nums, left, high) { + if (left >= high) { return; } - let i = low - 1; + let i = left - 1; let j = high + 1; - let x = nums[(low + high) >> 1]; + let x = nums[(left + high) >> 1]; while (i < j) { while (nums[++i] < x); while (nums[--j] > x); @@ -26,7 +26,7 @@ function quickSort(nums, low, high) { nums[j] = t; } } - quickSort(nums, low, j); + quickSort(nums, left, j); quickSort(nums, j + 1, high); } diff --git a/basic/sorting/QuickSort/Main.py b/basic/sorting/QuickSort/Main.py index 8da08c820a8f5..efa2294b30f69 100644 --- a/basic/sorting/QuickSort/Main.py +++ b/basic/sorting/QuickSort/Main.py @@ -2,11 +2,11 @@ nums = list(map(int, input().split())) -def quick_sort(nums, low, high): - if low >= high: +def quick_sort(nums, left, high): + if left >= high: return - i, j = low - 1, high + 1 - x = nums[(low + high) >> 1] + i, j = left - 1, high + 1 + x = nums[(left + high) >> 1] while i < j: while 1: i += 1 @@ -18,7 +18,7 @@ def quick_sort(nums, low, high): break if i < j: nums[i], nums[j] = nums[j], nums[i] - quick_sort(nums, low, j) + quick_sort(nums, left, j) quick_sort(nums, j + 1, high) diff --git a/basic/sorting/QuickSort/README.md b/basic/sorting/QuickSort/README.md index 57b5d769126d0..6053d17b478fb 100644 --- a/basic/sorting/QuickSort/README.md +++ b/basic/sorting/QuickSort/README.md @@ -5,12 +5,12 @@ **快速排序算法模板:** ```java -void quickSort(int[] nums, int low, int high) { - if (low >= high) { +void quickSort(int[] nums, int left, int high) { + if (left >= high) { return; } - int i = low - 1, j = high + 1; - int x = nums[low]; + int i = left - 1, j = high + 1; + int x = nums[left]; while (i < j) { while (nums[++i] < x); while (nums[--j] > x); @@ -20,7 +20,7 @@ void quickSort(int[] nums, int low, int high) { nums[j] = t; } } - quickSort(nums, low, j); + quickSort(nums, left, j); quickSort(nums, j + 1, high); } ``` @@ -72,11 +72,11 @@ N = int(input()) nums = list(map(int, input().split())) -def quick_sort(nums, low, high): - if low >= high: +def quick_sort(nums, left, high): + if left >= high: return - i, j = low - 1, high + 1 - x = nums[(low + high) >> 1] + i, j = left - 1, high + 1 + x = nums[(left + high) >> 1] while i < j: while 1: i += 1 @@ -88,7 +88,7 @@ def quick_sort(nums, low, high): break if i < j: nums[i], nums[j] = nums[j], nums[i] - quick_sort(nums, low, j) + quick_sort(nums, left, j) quick_sort(nums, j + 1, high) @@ -115,12 +115,12 @@ public class Main { } } - public static void quickSort(int[] nums, int low, int high) { - if (low >= high) { + public static void quickSort(int[] nums, int left, int high) { + if (left >= high) { return; } - int i = low - 1, j = high + 1; - int x = nums[low]; + int i = left - 1, j = high + 1; + int x = nums[left]; while (i < j) { while (nums[++i] < x); while (nums[--j] > x); @@ -130,7 +130,7 @@ public class Main { nums[j] = t; } } - quickSort(nums, low, j); + quickSort(nums, left, j); quickSort(nums, j + 1, high); } } @@ -150,14 +150,14 @@ let getInputArgs = line => { return line.split(' ').filter(s => s !== '').map(x => parseInt(x)); } -function quickSort(nums, low, high) { - if (low >= high) { +function quickSort(nums, left, high) { + if (left >= high) { return; } - let i = low - 1; + let i = left - 1; let j = high + 1; - let x = nums[(low + high) >> 1]; + let x = nums[(left + high) >> 1]; while (i < j) { while (nums[++i] < x); while (nums[--j] > x); @@ -167,7 +167,7 @@ function quickSort(nums, low, high) { nums[j] = t; } } - quickSort(nums, low, j); + quickSort(nums, left, j); quickSort(nums, j + 1, high); } @@ -192,12 +192,12 @@ package main import "fmt" -func quickSort(nums []int, low, high int) { - if low >= high { +func quickSort(nums []int, left, high int) { + if left >= high { return } - i, j := low-1, high+1 - x := nums[(low+high)>>1] + i, j := left-1, high+1 + x := nums[(left+high)>>1] for i < j { for { i++ @@ -215,7 +215,7 @@ func quickSort(nums []int, low, high int) { nums[i], nums[j] = nums[j], nums[i] } } - quickSort(nums, low, j) + quickSort(nums, left, j) quickSort(nums, j+1, high) }