diff --git a/5.leetcode/src/com/fanxb/common/Q153.java b/5.leetcode/src/com/fanxb/common/Q153.java new file mode 100644 index 0000000..4d18444 --- /dev/null +++ b/5.leetcode/src/com/fanxb/common/Q153.java @@ -0,0 +1,44 @@ +package com.fanxb.common; + +/** + * Created with IntelliJ IDEA + * 寻找旋转排序数组中的最小值 + * 地址: https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array/ + * 思路: 需要找到分界点 + * + * @author fanxb + * Date: 2020/6/11 9:56 + */ +public class Q153 { + public int findMin(int[] nums) { + int l = 0, r = nums.length - 1, mid; + int min = nums[0]; + while (l <= r) { + mid = (l + r) / 2; + if (nums[l] == nums[mid]) { + //无法判断l,r所处的位置,l++ + if (nums[l] < min) { + min = nums[l]; + } + l++; + } else if (nums[l] < nums[mid]) { + //说明两个点肯定都落在了左边的升续端内 + if (nums[l] < min) { + min = nums[l]; + } + l = mid + 1; + } else { + //说明l肯定在左边区间,mid肯定在右边区间 + if (nums[mid] < min) { + min = nums[mid]; + } + r = mid - 1; + } + } + return min; + } + + public static void main(String[] args) { + System.out.println(new Q153().findMin(new int[]{3, 4, 5, 1, 2})); + } +} diff --git a/5.leetcode/src/com/fanxb/common/Q154.java b/5.leetcode/src/com/fanxb/common/Q154.java new file mode 100644 index 0000000..021e2f2 --- /dev/null +++ b/5.leetcode/src/com/fanxb/common/Q154.java @@ -0,0 +1,44 @@ +package com.fanxb.common; + +/** + * Created with IntelliJ IDEA + * 寻找旋转排序数组中的最小值 II + * 地址: https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/ + * 思路: 部分二分查找法,当知道某一段是有序的时候就能够快速判断出这一段的最小值 + * + * @author fanxb + * Date: 2020/6/11 9:56 + */ +public class Q154 { + public int findMin(int[] nums) { + int l = 0, r = nums.length - 1, mid; + int min = Integer.MAX_VALUE; + while (l <= r) { + mid = (l + r) / 2; + if (nums[l] == nums[mid]) { + //无法判断哪边是有序的 + if (nums[l] < min) { + min = nums[mid]; + } + l++; + } else if (nums[l] < nums[mid]) { + //左边是有序的,找到了左边的最小值 + if (nums[l] < min) { + min = nums[l]; + } + l = mid + 1; + } else { + //右边是有续的,找到了右边的最小值 + if (nums[mid] < min) { + min = nums[mid]; + } + r = mid - 1; + } + } + return min; + } + + public static void main(String[] args) { + System.out.println(new Q154().findMin(new int[]{1, 0, 1, 1, 1})); + } +} diff --git a/5.leetcode/src/com/fanxb/common/Q34.java b/5.leetcode/src/com/fanxb/common/Q34.java new file mode 100644 index 0000000..fe1e764 --- /dev/null +++ b/5.leetcode/src/com/fanxb/common/Q34.java @@ -0,0 +1,69 @@ +package com.fanxb.common; + +import java.util.Arrays; + +/** + * Created with IntelliJ IDEA + * x 的平方根 + * 地址: https://leetcode-cn.com/problems/sqrtx/ + * 思路: 题目要求求解一个数的平方根的整数部分,那就那就相当于找到一个数num,使其满足num*mum==x || num*num<x && (num+1)*(num+1)>x + * 可通过二分查找来进行求解,num的值一定是[0,x]中的一个数 + * 1. 首先设定l=0,r=x + * 2. mid=(l+r)/2,temp1=mid*mid,temp2=(mid+1)*(mid+1) + * 3. 如果temp1 == x || (temp1 < x && temp2 > x)满足结果即为mid + * 4. 否则判断temp1>x,如果满足r=mid,重复2 + * 5. 否则l=mid,重复2 + * + * @author fanxb + * Date: 2020/6/11 9:56 + */ +public class Q34 { + public int[] searchRange(int[] nums, int target) { + if (nums.length == 0) { + return new int[]{-1, -1}; + } + int l = 0, r = nums.length - 1; + if (target < nums[0] || target > nums[r]) { + return new int[]{-1, -1}; + } + int mid; + while (true) { + mid = (l + r) / 2; + if (nums[mid] == target) { + break; + } else if (nums[mid + 1] == target) { + mid = mid + 1; + break; + } else if (nums[mid] < target) { + if (nums[mid + 1] > target) { + return new int[]{-1, -1}; + } + l = mid; + } else { + r = mid; + } + } + //从mid向两端查找 + l = mid; + r = mid; + while (true) { + boolean out = true; + if (l > 0 && nums[l - 1] == target) { + l--; + out = false; + } + if (r < nums.length - 1 && nums[r + 1] == target) { + r++; + out = false; + } + if (out) { + break; + } + } + return new int[]{l, r}; + } + + public static void main(String[] args) { + System.out.println(Arrays.toString(new Q34().searchRange(new int[]{1, 4}, 4))); + } +} diff --git a/5.leetcode/src/com/fanxb/common/Q4.java b/5.leetcode/src/com/fanxb/common/Q4.java new file mode 100644 index 0000000..4faecb0 --- /dev/null +++ b/5.leetcode/src/com/fanxb/common/Q4.java @@ -0,0 +1,46 @@ +package com.fanxb.common; + +import java.util.Arrays; + +/** + * Created with IntelliJ IDEA + * x 的平方根 + * 地址: https://leetcode-cn.com/problems/sqrtx/ + * 思路: 双路规避排序查找 + * + * + * @author fanxb + * Date: 2020/6/11 9:56 + */ +public class Q4 { + public double findMedianSortedArrays(int[] nums1, int[] nums2) { + int size = nums1.length + nums2.length; + boolean isDoubleSize = (size & 1) == 0; + if (nums1.length == 0) { + return nums2.length == 1 ? nums2[0] : isDoubleSize ? (nums2[size / 2 - 1] + nums2[size / 2]) / 2.0 : nums2[size / 2]; + } else if (nums2.length == 0) { + return nums1.length == 1 ? nums1[0] : isDoubleSize ? (nums1[size / 2 - 1] + nums1[size / 2]) / 2.0 : nums1[size / 2]; + } + + //二路归并找到中间两个位置的数 + int count = 0, i = 0, j = 0, value = 0; + while (count < size / 2) { + if (i == nums1.length) { + value = nums2[j++]; + } else if (j == nums2.length) { + value = nums1[i++]; + } else if (nums1[i] < nums2[j]) { + value = nums1[i++]; + } else { + value = nums2[j++]; + } + count++; + } + int value2 = i == nums1.length ? nums2[j] : j == nums2.length ? nums1[i] : Math.min(nums1[i], nums2[j]); + return isDoubleSize ? (value + value2) / 2.0 : value2; + } + + public static void main(String[] args) { + System.out.println(new Q4().findMedianSortedArrays(new int[]{2,3,4}, new int[]{1})); + } +} diff --git a/5.leetcode/src/com/fanxb/common/Q540.java b/5.leetcode/src/com/fanxb/common/Q540.java new file mode 100644 index 0000000..db751e9 --- /dev/null +++ b/5.leetcode/src/com/fanxb/common/Q540.java @@ -0,0 +1,31 @@ +package com.fanxb.common; + +/** + * Created with IntelliJ IDEA + * 寻找旋转排序数组中的最小值 II + * 地址: https://leetcode-cn.com/problems/find-minimum-in-rotated-sorted-array-ii/ + * 思路: 观察可以发现当没有异常点时,每个奇数位和偶数位都是一致的,一旦加入异常点会导致从异常点开始奇偶位的数不一直 + * + * @author fanxb + * Date: 2020/6/11 9:56 + */ +public class Q540 { + public int singleNonDuplicate(int[] nums) { + int l = 0, r = nums.length - 1, mid = 0; + while (l < r) { + mid = (l + r) / 2; + if ((mid + 1) % 2 == 0 ? nums[mid] == nums[mid - 1] : nums[mid] == nums[mid + 1]) { + //mid所处的位置,奇数位和偶数位的值一样,说明异常点在mid的后面 + l = mid + 1; + } else { + //说明异常点在mid或mid之前 + r = mid; + } + } + return nums[l]; + } + + public static void main(String[] args) { + System.out.println(new Q540().singleNonDuplicate(new int[]{1, 1, 2, 3, 3, 4, 4, 8, 8})); + } +} diff --git a/5.leetcode/src/com/fanxb/common/Q69.java b/5.leetcode/src/com/fanxb/common/Q69.java new file mode 100644 index 0000000..eddbbfe --- /dev/null +++ b/5.leetcode/src/com/fanxb/common/Q69.java @@ -0,0 +1,45 @@ +package com.fanxb.common; + +/** + * Created with IntelliJ IDEA + * x 的平方根 + * 地址: https://leetcode-cn.com/problems/sqrtx/ + * 思路: 题目要求求解一个数的平方根的整数部分,那就那就相当于找到一个数num,使其满足num*mum==x || num*num<x && (num+1)*(num+1)>x + * 可通过二分查找来进行求解,num的值一定是[0,x]中的一个数 + * 1. 首先设定l=0,r=x + * 2. mid=(l+r)/2,temp1=mid*mid,temp2=(mid+1)*(mid+1) + * 3. 如果temp1 == x || (temp1 < x && temp2 > x)满足结果即为mid + * 4. 否则判断temp1>x,如果满足r=mid,重复2 + * 5. 否则l=mid,重复2 + * + * + * + * @author fanxb + * Date: 2020/6/11 9:56 + */ +public class Q69 { + public int mySqrt(int x) { + if (x == 0 || x == 1) { + return x; + } + int l = 0, r = x; + long temp1, temp2, mid; + while (true) { + mid = (l + r) / 2; + temp1 = mid * mid; + temp2 = (mid + 1) * (mid + 1); + + if (temp1 == x || (temp1 < x && temp2 > x)) { + return (int) mid; + } else if (temp1 > x) { + r = (int) mid; + } else { + l = (int) mid; + } + } + } + + public static void main(String[] args) { + System.out.println(new Q69().mySqrt(2147395599)); + } +} diff --git a/5.leetcode/src/com/fanxb/common/Q81.java b/5.leetcode/src/com/fanxb/common/Q81.java new file mode 100644 index 0000000..49439a5 --- /dev/null +++ b/5.leetcode/src/com/fanxb/common/Q81.java @@ -0,0 +1,53 @@ +package com.fanxb.common; + +import java.util.Arrays; + +/** + * Created with IntelliJ IDEA + * x 的平方根 + * 地址: https://leetcode-cn.com/problems/sqrtx/ + * 思路: + * + * @author fanxb + * Date: 2020/6/11 9:56 + */ +public class Q81 { + public boolean search(int[] nums, int target) { + if (nums.length == 0) { + return false; + } + int l = 0, r = nums.length - 1; + int mid; + while (l <= r) { + mid = (l + r) / 2; + if (nums[mid] == target) { + return true; + } + if (nums[l] == nums[mid]) { + //无法分辨哪边是有序的 + l++; + continue; + } + if (nums[l] < nums[mid]) { + //说明[l,mid]是有序的 + if (nums[mid] > target && nums[l] <= target) { + r = mid - 1; + } else { + l = mid + 1; + } + } else { + //说明[mid,r]是有序的 + if (nums[mid] < target && nums[r] >= target) { + l = mid + 1; + } else { + r = mid - 1; + } + } + } + return false; + } + + public static void main(String[] args) { + System.out.println(new Q81().search(new int[]{1,0,1,1,1}, 0)); + } +} diff --git a/5.leetcode/src/com/fanxb/common/Sort.java b/5.leetcode/src/com/fanxb/common/Sort.java new file mode 100644 index 0000000..02c4a21 --- /dev/null +++ b/5.leetcode/src/com/fanxb/common/Sort.java @@ -0,0 +1,83 @@ +package com.fanxb.common; + +import java.util.Arrays; + +/** + * 排序 + * + * @author fanxb + * @date 2021/4/4 + **/ +public class Sort { + + /** + * 冒泡排序 + * + * @author fanxb + * @date 2021/4/4 + **/ + public static int[] sort1(int[] arr) { + for (int i = 0; i < arr.length - 1; i++) { + for (int j = 0, length = arr.length - 1 - i; j < length; j++) { + if (arr[j] > arr[j + 1]) { + int temp = arr[j + 1]; + arr[j + 1] = arr[j]; + arr[j] = temp; + } + } + } + return arr; + } + + public static void quickSort(int[] arr, int start, int end) { + if (end - start <= 1) { + return; + } + int l = start, r = end, base = arr[start]; + while (l < r) { + //右边找到一个小于base的然后交换 + while (arr[r] >= base && l < r) { + r--; + } + //左边找到一个大于base的 + while (arr[l] <= base && l < r) { + l++; + } + int temp = arr[l]; + arr[l] = arr[r]; + arr[r] = temp; + } + //交换start和i的位置,使base左边的都小于等于base,右边的都大于等于base + arr[start] = arr[l]; + arr[l] = base; + + //对l左边和右边的分别进行快拍 + quickSort(arr, start, l - 1); + quickSort(arr, l + 1, end); + } + + /** + * 插入排序 + * + * @author fanxb + * @date 2021/4/4 + **/ + public static void insertSort(int[] arr) { + for (int i = 0; i < arr.length - 1; i++) { + for (int j = i + 1; j > 0 && arr[j - 1] > arr[j]; j--) { + int temp = arr[j - 1]; + arr[j - 1] = arr[j]; + arr[j] = temp; + } + } + } + + + public static void main(String[] args) { + int[] s = {23, 49, 13, 12, 45, 393, 21, 21048, 12}; +// System.out.println(Arrays.toString(sort1(s))); +// quickSort(s, 0, s.length - 1); + insertSort(s); + System.out.println(Arrays.toString(s)); + } +}