();
+ for (int i = 0; i < n; i++) { + int num = nums[i]; + int targetVal = target - num; + arrayMap.put(targetVal, i); + } + for (int i = 0; i < n; i++) { + int num = nums[i]; + if (arrayMap.containsKey(num)) { + int index = arrayMap.get(num); + if (index> i) {
+ return new int[]{i, index};
+ } else {
+ return new int[]{index, i};
+ }
+ }
+ }
+ return new int[0];
+ }
+
+ /**
+ * 暴力破解法
+ * 时间复杂度:o(n^2)
+ * 空间复杂度:O(n)
+ * @param nums
+ * @param target
+ * @return
+ */
+ private int[] forceSolution(int[] nums, int target) {
+ int n = nums.length;
+ for (int i = 0; i < n; i++) { + int num = nums[i]; + int val = target - num; + for (int j = i + 1; j < n; j++) { + if (nums[j] == val) { + return new int[]{i, j}; + } + } + } + return new int[0]; + } +} diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/TwoSumII.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/TwoSumII.java new file mode 100644 index 0000000..79147f1 --- /dev/null +++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/TwoSumII.java @@ -0,0 +1,62 @@ +package com.bruis.algorithminjava.algorithm.leetcode; + +/** + * @Description + * @Author luohaiyang + * @Date 2022/4/28 + */ +public class TwoSumII { + public int[] twoSum(int[] numbers, int target) { + return twoPointer(numbers, target); + } + + /** + * 双指针 + * 时间复杂度:O(n) + * 空间复杂度:O(1) + * @param numbers + * @param target + * @return + */ + private int[] twoPointer(int[] numbers, int target) { + int n = numbers.length; + if (n < 2) { + return numbers; + } + int i = 0, j = n - 1; + while (i < j) { + if (numbers[i] + numbers[j] == target) { + return new int[]{i + 1, j + 1}; + } + if (numbers[i] + numbers[j]> target) {
+ j--;
+ } else {
+ i++;
+ }
+ }
+ return new int[0];
+ }
+
+ /**
+ * 暴力法:
+ * 时间复杂度:O(n^2)
+ * 空间复杂度:O(1)
+ * @param numbers
+ * @param target
+ * @return
+ */
+ private int[] forceSolution(int[] numbers, int target) {
+ int n = numbers.length;
+ if (n < 2) { + return numbers; + } + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + if (numbers[i] + numbers[j] == target) { + return new int[]{i + 1, j + 1}; + } + } + } + return new int[0]; + } +} diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/IsPalindrome.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/IsPalindrome.java new file mode 100644 index 0000000..d75488f --- /dev/null +++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/IsPalindrome.java @@ -0,0 +1,41 @@ +package com.bruis.algorithminjava.algorithm.leetcode.array; + +/** + * + * 125 + * + * 验证回文串 + * + * https://leetcode-cn.com/problems/valid-palindrome/ + * + * + * @author LuoHaiYang + */ +public class IsPalindrome { + public boolean isPalindrome(String str) { + int head = 0, tail = str.length() - 1; + char a, b; + while(head < tail) { + a = str.charAt(head); + b = str.charAt(tail); + if(!Character.isLetterOrDigit(a)) { + head ++; + } else if(!Character.isLetterOrDigit(b)) { + tail --; + } else { + if(Character.toLowerCase(a) != Character.toLowerCase(b)) { + return false; + } + head ++; + tail --; + } + } + return true; + } + + public static void main(String[] args) { + IsPalindrome isPalindrome = new IsPalindrome(); + String test = "race a car"; + System.out.println(isPalindrome.isPalindrome(test)); + } +} diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/MaximumGap.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/MaximumGap.java new file mode 100644 index 0000000..522d1f0 --- /dev/null +++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/MaximumGap.java @@ -0,0 +1,170 @@ +package com.bruis.algorithminjava.algorithm.leetcode.array; + +import java.util.Arrays; + +/** + * 最大间距 + * + * url:https://leetcode-cn.com/problems/maximum-gap/ + * + * @author LuoHaiYang + */ +public class MaximumGap { + + /** + * 基于桶排序 + * 时间复杂度:O(N) + * 空间复杂度:O(N) + * @param nums + * @return + */ + public int maximumGapOptimize2(int[] nums) { + if (nums.length < 2) return 0; + int len = nums.length; + + // 找出最大值和最小值 为了方便后面确定桶的数量 + int max = -1, min = Integer.MAX_VALUE; + for (int i = 0; i < len; i++) { + max = Math.max(nums[i], max); + min = Math.min(nums[i], min); + } + + // 排除nums全部为一样的数字,nums = [1,1,1,1,1,1]; + if (max - min == 0) return 0; + // 用于存放每个桶的最大值 + int[] bucketMin = new int[len - 1]; + // 用于存放每个桶的最小值 + int[] bucketMax = new int[len - 1]; + Arrays.fill(bucketMax, -1); + Arrays.fill(bucketMin, Integer.MAX_VALUE); + + // 确定桶的间距 + int interval = (int)Math.ceil((double)(max - min) / (len - 1)); + for (int i = 0; i < len; i++) { + // 找到每一个值所对应桶的索引 + int index = (nums[i] - min) / interval; + if (nums[i] == min || nums[i] == max) continue; + // 更新每个桶的数据 + bucketMax[index] = Math.max(bucketMax[index], nums[i]); + bucketMin[index] = Math.min(bucketMin[index], nums[i]); + } + + // maxGap 表示桶之间最大的差距 + int maxGap = 0; + // preMax 表示前一个桶的最大值 + int preMax = min; + for (int i = 0; i < len - 1; i++) { + // 表示某一个桶为空 + // 但凡某一个桶不为空,都会在前面的数据中更新掉bucketMax的值 + if (bucketMax[i] == -1) continue; + maxGap = Math.max(bucketMin[i] - preMax, maxGap); + preMax = bucketMax[i]; + } + // [1,10000000] + maxGap = Math.max(maxGap, max - preMax); + return maxGap; + } + + /** + * 基数排序: + * 时间复杂度:O(N) + * 空间复杂度:O(N) + * @param nums + * @return + */ + public int maximumGapOptimize(int[] nums) { + int n = nums.length; + if (n < 2) { + return 0; + } + long exp = 1; + int[] buf = new int[n]; + int maxVal = Arrays.stream(nums).max().getAsInt(); + + while (maxVal>= exp) {
+ int[] cnt = new int[10];
+ for (int i = 0; i < n; i++) { + int digit = (nums[i] / (int) exp) % 10; + cnt[digit]++; + } + for (int i = 1; i < 10; i++) { + cnt[i] += cnt[i - 1]; + } + for (int i = n - 1; i>= 0; i--) {
+ int digit = (nums[i] / (int) exp) % 10;
+ buf[cnt[digit] - 1] = nums[i];
+ cnt[digit]--;
+ }
+ System.arraycopy(buf, 0, nums, 0, n);
+ exp *= 10;
+ }
+
+ int ret = 0;
+ for (int i = 1; i < n; i++) { + ret = Math.max(ret, nums[i] - nums[i - 1]); + } + return ret; + } + + public int maximumGap(int[] nums) { + if (nums == null || nums.length < 2) { + return 0; + } + // 排序 + quickSort(nums); + int n = nums.length; + + int max = nums[1] - nums[0]; + + for (int i = 2; i < n; i++) { + max = max(max, nums[i] - nums[i-1]); + } + return max; + } + + private void quickSort(int[] nums) { + int n = nums.length; + quickSort3ways(nums, 0, n-1); + } + + private void quickSort3ways(int[] nums, int left, int right) { + if (left>= right) {
+ return;
+ }
+ int p = nums[left];
+ int i = left + 1, lt = left, gt = right + 1;
+
+ while (i < gt) { + if (nums[i] < p) { + swap(nums, i, lt + 1); + i++; + lt++; + } else if (nums[i]> p) {
+ swap(nums, i, gt - 1);
+ gt--;
+ } else {
+ i++;
+ }
+ }
+ swap(nums, left, lt);
+ quickSort3ways(nums, left, lt - 1);
+ quickSort3ways(nums, gt, right);
+ }
+
+ private int max(int i, int j) {
+ return Math.max(i, j);
+ }
+
+ private void swap(int[] nums, int i, int j) {
+ int tmp = nums[i];
+ nums[i] = nums[j];
+ nums[j] = tmp;
+ }
+
+ public static void main(String[] args) {
+ int[] test = {3,6,9,1,20,15,11,30,31};
+ MaximumGap maximumGap = new MaximumGap();
+// System.out.println(maximumGap.maximumGap(test));
+ System.out.println(maximumGap.maximumGapOptimize2(test));
+ }
+}
diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/array/MaximumProductSubarray.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/MaximumProductSubarray.java
similarity index 96%
rename from src/main/java/com/bruis/algorithminjava/algorithm/array/MaximumProductSubarray.java
rename to src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/MaximumProductSubarray.java
index 2df3ade..b0785f4 100644
--- a/src/main/java/com/bruis/algorithminjava/algorithm/array/MaximumProductSubarray.java
+++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/MaximumProductSubarray.java
@@ -1,4 +1,4 @@
-package com.bruis.algorithminjava.algorithm.array;
+package com.bruis.algorithminjava.algorithm.leetcode.array;
/**
* @author LuoHaiYang
diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ReversePairs.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ReversePairs.java
new file mode 100644
index 0000000..fc2d98c
--- /dev/null
+++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ReversePairs.java
@@ -0,0 +1,179 @@
+package com.bruis.algorithminjava.algorithm.leetcode.array;
+
+import java.util.Arrays;
+
+/**
+ * 逆序对
+ *
+ * url: https://leetcode-cn.com/problems/shu-zu-zhong-de-ni-xu-dui-lcof/
+ *
+ * @author LuoHaiYang
+ */
+public class ReversePairs {
+
+ /* ================================ 解法一 ================================*/
+
+ /**
+ * 暴力解法O(n^2),超时
+ *
+ * @param nums
+ * @return
+ */
+ public int reversePairs2(int[] nums) {
+ int n = nums.length;
+ if (n < 2) { + return 0; + } + int reverseNum = 0; + for (int i = 0; i < n; i++) { + for (int j = i + 1; j < n; j++) { + if (nums[i]> nums[j]) {
+ reverseNum++;
+ }
+ }
+ }
+ return reverseNum;
+ }
+
+ /* ================================ 解法二 ================================*/
+
+ /**
+ * 使用自顶向下的归并排序算法计算逆序对,用来额外的空间。
+ *
+ * @param nums
+ * @return
+ */
+ public int reversePairs(int[] nums) {
+ int n = nums.length;
+ if (n < 2) { + return 0; + } + return getReversePairs(nums); + } + + private int getReversePairs(int[] nums) { + int n = nums.length; + return getReversePairs(nums, 0, n - 1); + } + + private int getReversePairs(int[] nums, int left, int right) { + if (left>= right) {
+ return 0;
+ }
+ int result = 0;
+ int mid = (left + right) / 2;
+ result += getReversePairs(nums, left, mid) + getReversePairs(nums, mid + 1, right) + reversePairs(nums, left, mid, right);
+ return result;
+ }
+
+ private int reversePairs(int[] nums, int left, int mid, int right) {
+ int[] aux = Arrays.copyOfRange(nums, left, right + 1);
+ int i = left, j = mid + 1;
+
+ int res = 0;
+
+ for (int k = left; k <= right; k++) { + if (i> mid) {
+ nums[k] = aux[j - left];
+ j++;
+ } else if (j> right) {
+ nums[k] = aux[i - left];
+ i++;
+ } else if (aux[i - left] <= aux[j - left]) { + nums[k] = aux[i - left]; + i++; + } else { + nums[k] = aux[j - left]; + j++; + res += (mid - i) + 1; + } + } + return res; + } + + /* ================================ 题解三(优化) ================================*/ + + /** + * + * 相比解法二时间复杂度常数和空间复杂度更低 + * + * @param nums + * @return + */ + public int reversePairs3(int[] nums) { + if (nums == null || nums.length < 2) { + return 0; + } + int[] temp = new int[nums.length]; + System.arraycopy(nums, 0, temp, 0, nums.length); + + int count = mergeCount(nums, temp, 0, nums.length - 1); + return count; + } + + private int mergeCount(int[] nums, int[] temp, int start, int end) { + if (start>= end) {
+ return 0;
+ }
+
+ int mid = (start + end)>> 1;
+ int left = mergeCount(temp, nums, start, mid);
+ int right = mergeCount(temp, nums, mid + 1, end);
+ int count = 0;
+
+ //merge()
+ //遍历左区域指针
+ int i = mid;
+ //遍历右区域指针
+ int j = end;
+
+ //临时区域指针
+ int k = end;
+ while (i>= start && j>= mid + 1) {
+ if (nums[i]> nums[j]) {
+ count += j - mid;
+ temp[k--] = nums[i--];
+ } else {
+ temp[k--] = nums[j--];
+ }
+ }
+
+ //如果还有剩下没遍历的
+ while (i>= start) {
+ temp[k--] = nums[i--];
+ }
+ while (j>= mid + 1) {
+ temp[k--] = nums[j--];
+ }
+
+ return count + left + right;
+ }
+
+ public int reversePairs4(int[] nums) {
+ if (nums == null || nums.length < 2) { + return 0; + } + int[] temp = new int[nums.length]; + System.arraycopy(nums, 0, temp, 0, nums.length); + //int count = mergeCount2(); + return 0; + } + + private int mergeCount2(int[] nums, int[] temp, int start, int end) { + if (start>= end) {
+ return 0;
+ }
+ int mid = (start + end) << 1; + //int left = mergeCount2(nums, ); + return 0; + } + + public static void main(String[] args) { + ReversePairs reversePairs = new ReversePairs(); + int[] nums = {7, 5, 6, 4}; + //int[] nums = {1,3,2,3,1}; + System.out.println(reversePairs.reversePairs3(nums)); + } + + +} diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ReverseVowels.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ReverseVowels.java new file mode 100644 index 0000000..5dbb8aa --- /dev/null +++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ReverseVowels.java @@ -0,0 +1,58 @@ +package com.bruis.algorithminjava.algorithm.leetcode.array; + +/** + * + * 345 + * + * https://leetcode-cn.com/problems/reverse-vowels-of-a-string/ + * + * 反转字符串中的元音字母 + * + * @author LuoHaiYang + */ +public class ReverseVowels { + + public String reverseVowels(String s) { + + char[] arr = s.toCharArray(); + int n = arr.length, left = 0, right = n - 1; + + while (left <= right) { + + // 如果不是元音,则指针右移 + while (left < n && !isVowel(arr[left])) { + left++; + } + + while (right>= 0 && !isVowel(arr[right])) {
+ right--;
+ }
+
+ if (left> right) {
+ break;
+ }
+
+ // 字符调换
+ swap(arr, left, right);
+ left++;
+ right--;
+ }
+ return new String(arr);
+ }
+
+ /**
+ *
+ * 1. 元音字母是?
+ *
+ */
+ private boolean isVowel(char ch) {
+ return ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u'
+ || ch == 'A' || ch == 'E' || ch == 'I' || ch == 'O' || ch == 'U';
+ }
+
+ private void swap(char[] arr, int i, int j) {
+ char tmp = arr[i];
+ arr[i] = arr[j];
+ arr[j] = tmp;
+ }
+}
diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/SortColors.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/SortColors.java
new file mode 100644
index 0000000..26fe731
--- /dev/null
+++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/SortColors.java
@@ -0,0 +1,56 @@
+package com.bruis.algorithminjava.algorithm.leetcode.array;
+
+/**
+ *
+ * 颜色分类
+ *
+ * url:https://leetcode-cn.com/problems/sort-colors/
+ *
+ * @author LuoHaiYang
+ */
+public class SortColors {
+
+ public void sortColors(int[] nums) {
+ if (nums == null || nums.length < 2) { + return; + } + sort(nums, 0, nums.length - 1); + } + + private void sort(int[] nums, int left, int right) { + if (left>= right) {
+ return;
+ }
+
+ int p = nums[left];
+ int i = left + 1, lt = left, gt = right + 1;
+
+ while (i < gt) { + if (nums[i] < p) { + swap(nums, i, lt + 1); + i++; + lt++; + } else if (nums[i]> p) {
+ swap(nums, i, gt - 1);
+ gt--;
+ } else {
+ i++;
+ }
+ }
+ swap(nums, left, lt);
+ sort(nums, left, lt - 1);
+ sort(nums, gt, right);
+ }
+
+ private void swap(int[] nums, int i, int j) {
+ int tmp = nums[i];
+ nums[i] = nums[j];
+ nums[j] = tmp;
+ }
+
+ public static void main(String[] args) {
+ SortColors sortColors = new SortColors();
+ int[] test = {0, 1};
+ sortColors.sortColors(test);
+ }
+}
diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/array/SubarraySumEqualsK.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/SubarraySumEqualsK.java
similarity index 98%
rename from src/main/java/com/bruis/algorithminjava/algorithm/array/SubarraySumEqualsK.java
rename to src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/SubarraySumEqualsK.java
index 82e703f..c7a7819 100644
--- a/src/main/java/com/bruis/algorithminjava/algorithm/array/SubarraySumEqualsK.java
+++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/SubarraySumEqualsK.java
@@ -1,4 +1,4 @@
-package com.bruis.algorithminjava.algorithm.array;
+package com.bruis.algorithminjava.algorithm.leetcode.array;
import java.util.HashMap;
import java.util.Map;
diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/array/ThreeSum.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ThreeSum.java
similarity index 98%
rename from src/main/java/com/bruis/algorithminjava/algorithm/array/ThreeSum.java
rename to src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ThreeSum.java
index 65d6ea4..435fa3a 100644
--- a/src/main/java/com/bruis/algorithminjava/algorithm/array/ThreeSum.java
+++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/ThreeSum.java
@@ -1,4 +1,4 @@
-package com.bruis.algorithminjava.algorithm.array;
+package com.bruis.algorithminjava.algorithm.leetcode.array;
import java.util.ArrayList;
import java.util.Arrays;
diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TopKFrequentElements.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TopKFrequentElements.java
new file mode 100644
index 0000000..705e368
--- /dev/null
+++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TopKFrequentElements.java
@@ -0,0 +1,69 @@
+package com.bruis.algorithminjava.algorithm.leetcode.array;
+
+import java.util.*;
+
+/**
+ *
+ * 前K个高频元素
+ *
+ * url:https://leetcode-cn.com/problems/top-k-frequent-elements/
+ *
+ * @author LuoHaiYang
+ */
+public class TopKFrequentElements {
+
+ /**
+ *
+ * 桶排序
+ *
+ */
+ public int[] topKFrequent(int[] nums, int k) {
+ List res = new ArrayList();
+
+ if (nums == null || nums.length < 2) { + return nums; + } + Map count = new LinkedHashMap();
+ int n = nums.length;
+
+ for (int i = 0; i < n; i++) { + if (count.containsKey(nums[i])) { + count.put(nums[i], count.get(nums[i]) + 1); + } else { + count.put(nums[i], 1); + } + } + + List[] list = new List[nums.length];
+ for (int key : count.keySet()) {
+ // 让频率作为下标
+ int i = count.get(key);
+ if (list[i] == null) {
+ list[i] = new ArrayList();
+ }
+ // key表示的是元素
+ list[i].add(key);
+ }
+
+ for (int i = list.length - 1; i>= 0 && res.size() < k; i--) { + if (list[i] == null) { + continue; + } + res.addAll(list[i]); + + } + int[] result = new int[res.size()]; + for (int i = 0; i < res.size(); i++) { + result[i] = res.get(i); + } + return result; + } + + public static void main(String[] args) { + TopKFrequentElements topKFrequentElements = new TopKFrequentElements(); + //int[] test = {1,1,1,2,2,3}; + int[] test = {3,0,1,0}; + topKFrequentElements.topKFrequent(test,1); + + } +} diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/array/TwoSum.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TwoSum.java similarity index 97% rename from src/main/java/com/bruis/algorithminjava/algorithm/array/TwoSum.java rename to src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TwoSum.java index 6d8097e..08d7dcc 100644 --- a/src/main/java/com/bruis/algorithminjava/algorithm/array/TwoSum.java +++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TwoSum.java @@ -1,4 +1,4 @@ -package com.bruis.algorithminjava.algorithm.array; +package com.bruis.algorithminjava.algorithm.leetcode.array; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TwoSumII.java b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TwoSumII.java new file mode 100644 index 0000000..deb5cff --- /dev/null +++ b/src/main/java/com/bruis/algorithminjava/algorithm/leetcode/array/TwoSumII.java @@ -0,0 +1,38 @@ +package com.bruis.algorithminjava.algorithm.leetcode.array; + +/** + * 167: + * + * https://leetcode-cn.com/problems/two-sum-ii-input-array-is-sorted/description/?utm_source=LCUS&utm_medium=ip_redirect_q_uns&utm_campaign=transfer2china + * + * 思路:指针碰撞 + * + * @author LuoHaiYang + */ +public class TwoSumII { + + public int[] twoSum(int[] numbers, int target) { + + if (numbers.length < 2) { + return numbers; + } + + int left = 0, right = numbers.length - 1; + + while (left <= right) { + + int result = numbers[left] + numbers[right]; + + if (result == target) { + int[] res = {left + 1, right + 1}; + return res; + } else if (result> target) {
+ right --;
+ } else {
+ left ++;
+ }
+ }
+
+ return numbers;
+ }
+}
diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/sort/BinarySearch.java b/src/main/java/com/bruis/algorithminjava/algorithm/sort/BinarySearch.java
new file mode 100644
index 0000000..b6de14f
--- /dev/null
+++ b/src/main/java/com/bruis/algorithminjava/algorithm/sort/BinarySearch.java
@@ -0,0 +1,31 @@
+package com.bruis.algorithminjava.algorithm.sort;
+
+/**
+ *
+ * 二分查找法
+ *
+ * @author LuoHaiYang
+ */
+public class BinarySearch {
+
+ public static int binarySearch(int[] arr, int n, int target) {
+
+ // 在 [left, right]范围里寻找target
+ int left = 0, right = n - 1;
+
+ while (left <= right) { + int mid = (right + left) / 2; + int nums = arr[mid]; + + if (nums == target) { + return mid; + } else if (nums> target) {
+ left = mid + 1;
+ } else {
+ // nums < target + right = mid - 1; + } + } + return -1; + } +} diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/sort/BucketSort.java b/src/main/java/com/bruis/algorithminjava/algorithm/sort/BucketSort.java new file mode 100644 index 0000000..08c7be4 --- /dev/null +++ b/src/main/java/com/bruis/algorithminjava/algorithm/sort/BucketSort.java @@ -0,0 +1,57 @@ +package com.bruis.algorithminjava.algorithm.sort; + +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; + +/** + * 桶排序 + * + * @author LuoHaiYang + */ +public class BucketSort { + /* 排序原理: + + 桶排序本质就是空间换时间:时间复杂度为:O(n) + + 顺序从待排数组中取出数字,首先6被取出,然后把6入6号桶,这个过程类似这样:空桶[ 待排数组[ 0 ] ] = 待排数组[ 0 ] + [6 2 4 1 5 9] 待排数组 + [0 0 0 0 0 0 6 0 0 0] 空桶 + [0 1 2 3 4 5 6 7 8 9] 桶编号(实际不存在) + 顺序从待排数组中取出下一个数字,此时2被取出,将其放入2号桶,是几就放几号桶 + [6 2 4 1 5 9] 待排数组 + [0 0 2 0 0 0 6 0 0 0] 空桶 + [0 1 2 3 4 5 6 7 8 9] 桶编号(实际不存在) + 3,4,5,6省略,过程一样,全部入桶后变成下边这样 + [6 2 4 1 5 9] 待排数组 + [0 1 2 0 4 5 6 0 0 9] 空桶 + [0 1 2 3 4 5 6 7 8 9] 桶编号(实际不存在) + */ + private int range = 0; + public BucketSort(int range) { + this.range = range; + } + public int[] doSort(int[] arr) { + // 集合数组 + List[] aux = new LinkedList[range];
+ for (int i = 0; i < aux.length; i++) { + aux[i] = new LinkedList();
+ }
+ for (int i = 0; i < arr.length; i++) { + aux[arr[i]].add(arr[i]); + } + for (int i = 0, j = 0; i < aux.length && j < arr.length; i++) { + for (int v : aux[i]) { + arr[j] = v; + j++; + } + } + return arr; + } + + public static void main(String[] args) { + BucketSort bucketSort = new BucketSort(10); + int[] sort = bucketSort.doSort(new int[]{4, 1, 3, 2, 20, 6, 9, 9, 21, 19}); + System.out.println(Arrays.toString(sort)); + } +} diff --git a/src/main/java/com/bruis/algorithminjava/algorithm/sort/Heap.java b/src/main/java/com/bruis/algorithminjava/algorithm/sort/Heap.java new file mode 100644 index 0000000..f593c19 --- /dev/null +++ b/src/main/java/com/bruis/algorithminjava/algorithm/sort/Heap.java @@ -0,0 +1,122 @@ +package com.bruis.algorithminjava.algorithm.sort; + +/** + * 此堆索引从0开始 + * + * @Description + * @Author luohaiyang + * @Date 2022/4/20 + */ +public class Heap { + private int[] data; + private int count; + private int capacity; + + /** + * + * + * + * a + 1 + b c + 2 3 + d e f g + 4 5 6 7 + q w r x + 8 9 10 11 + * + * + * + * + */ + + /** + * 初始化堆 + * @param capacity + */ + public Heap(int capacity) { + this.capacity = capacity; + data = new int[capacity+1]; + count = 0; + } + + public Heap(int[] data, int capacity) { + this.data = data; + heapify(capacity); + } + + /** + * 新增一个元素 + * @param value + */ + public void insert(int value) { + if (count + 1> capacity) {
+ // 抛异常
+ }
+ data[++count] = value;
+ shiftUp(count);
+ }
+
+ /**
+ * 获取堆顶值
+ * @return
+ */
+ public int extractMax() {
+ if (count < 1) { + // 抛异常 + } + int max = data[1]; + swap(1, count--); + shiftDown(1); + return max; + } + + /** + * 堆化 + */ + public void heapify(int k) { + while (k/2>= 1) {
+ shiftDown(k/2);
+ k--;
+ }
+ }
+
+ public int size() {
+ return count;
+ }
+
+ public boolean isEmpty() {
+ return count == 0;
+ }
+
+ /**
+ * 上浮操作
+ * @param k
+ */
+ private void shiftUp(int k) {
+ while (k> 1 && data[k]> data[k/2]) {
+ swap(k, k/2);
+ k /= 2;
+ }
+ }
+
+ /**
+ * 下层操作
+ * @param k
+ */
+ private void shiftDown(int k) {
+ while (count>= k * 2) {
+ int j = k * 2;
+ if (j+1 <= count && data[j] < data[j+1]) j++; + if (data[k]>= data[j]) break;
+ swap(k, j);
+ k = j;
+ }
+ }
+
+ private void swap(int a, int b) {
+ int tmp = data[a];
+ data[a] = data[b];
+ data[b] = tmp;
+ }
+}