diff --git a/code/src/main/java/com/raorao/leetcode/q004/FindMedian.java b/code/src/main/java/com/raorao/leetcode/q004/FindMedian.java new file mode 100644 index 00000000..4ec45aa2 --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q004/FindMedian.java @@ -0,0 +1,88 @@ +package com.raorao.leetcode.q004; + +/** + * 寻找中位数. + * + * 问题描述:给定两个有序的数组,然后寻找两个有序数组的中位数。 + * + * 利用二分法的思想。时间复杂度为O(log(min(M,N)) 空间复杂度O(1) + * + * @author Xiong Raorao + * @since 2018-08-21-11:57 + */ +public class FindMedian { + + public static void main(String[] args) { + int[] nums1 = new int[] {1, 3}; + int[] nums2 = new int[] {2}; + System.out.println(new FindMedian().findMedianSortedArrays(nums1, nums2)); + } + + /* + * @param A: An integer array + * @param B: An integer array + * @return: a double whose format is *.5 or *.0 + */ + public double findMedianSortedArrays(int[] A, int[] B) { + int n = A.length + B.length; + + if (n % 2 == 0) { + return (findKth(A, B, n / 2) + findKth(A, B, n / 2 + 1)) / 2.0; + } + + return findKth(A, B, n / 2 + 1); + } + + // k is not zero-based, it starts from 1 + public int findKth(int[] A, int[] B, int k) { + if (A.length == 0) { + return B[k - 1]; + } + if (B.length == 0) { + return A[k - 1]; + } + + int start = Math.min(A[0], B[0]); + int end = Math.max(A[A.length - 1], B[B.length - 1]); + + // find first x that >= k numbers is smaller or equal to x + while (start + 1 < end) { + int mid = start + (end - start) / 2; + if (countSmallerOrEqual(A, mid) + countSmallerOrEqual(B, mid) < k) { + start = mid; + } else { + end = mid; + } + } + + if (countSmallerOrEqual(A, start) + countSmallerOrEqual(B, start) >= k) { + return start; + } + + return end; + } + + private int countSmallerOrEqual(int[] arr, int number) { + int start = 0, end = arr.length - 1; + + // find first index that arr[index] > number; + while (start + 1 < end) { + int mid = start + (end - start) / 2; + if (arr[mid] <= number) { + start = mid; + } else { + end = mid; + } + } + + if (arr[start] > number) { + return start; + } + + if (arr[end] > number) { + return end; + } + + return arr.length; + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q069/Sqrt.java b/code/src/main/java/com/raorao/leetcode/q069/Sqrt.java new file mode 100644 index 00000000..ad907be1 --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q069/Sqrt.java @@ -0,0 +1,33 @@ +package com.raorao.leetcode.q069; + +/** + * 求开方. + * + * @author Xiong Raorao + * @since 2018-08-21-16:06 + */ +public class Sqrt { + + /** + * 二分查找实现开方 + */ + public int mySqrt(int x) { + if (x <= 1) { + return x; + } + int low = 0; + int high = x; + while (low <= high) { + int mid = low + (high - low) / 2; + int sqrt = x / mid; + if (sqrt == mid) { + return mid; + } else if (mid > sqrt) { + high = mid - 1; + } else { + low = mid + 1; + } + } + return high; + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q075/SortColor.java b/code/src/main/java/com/raorao/leetcode/q075/SortColor.java new file mode 100644 index 00000000..81d8b60b --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q075/SortColor.java @@ -0,0 +1,45 @@ +package com.raorao.leetcode.q075; + +import java.util.Arrays; + +/** + * 荷兰国旗问题. + * + * 给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。 + * + * 它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间: 小于切分元素、等于切分元素、大于切分元素,而该算法是将数组分成三个区间:等于红色、等于白色、等于蓝色。 + * + * 题目描述只有0/1/2三种颜色,分别对应红白蓝 + * + * @author Xiong Raorao + * @since 2018-08-21-9:34 + */ +public class SortColor { + + public static void main(String[] args) { + int[] input = new int[] {2,0,1}; + new SortColor().sortColors(input); + Arrays.stream(input).forEach(e -> System.out.print(e + " ")); + } + + public void sortColors(int[] nums) { + int low = 0; + int high = nums.length - 1; + int pivot = 0; + while (pivot <= high) { + if (nums[pivot] == 0) { + swap(nums, pivot++, low++); // 如果把当前0换到前面去了,换过来的只可能是1或0,因此pivot右移 + } else if (nums[pivot] == 2) { + swap(nums, pivot, high--); // 如果是2和末尾的交换,可能过来的是0,因此pivot不能右移 + } else { + pivot++; + } + } + } + + private void swap(int[] arr, int i, int j) { + int tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q153/FindMin.java b/code/src/main/java/com/raorao/leetcode/q153/FindMin.java new file mode 100644 index 00000000..7ee29d43 --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q153/FindMin.java @@ -0,0 +1,46 @@ +package com.raorao.leetcode.q153; + +/** + * 旋转后的有序数组的最小数字. + * + * 当年拼多多二面的算法题啊 + * + * @author Xiong Raorao + * @since 2018-08-21-16:33 + */ +public class FindMin { + + public static void main(String[] args) { + int[] input = new int[] {4, 5, 6, 7, 0, 1, 2}; + int res = findMin(input); + System.out.println(res); + } + + public static int findMin(int[] nums) { + int low = 0; + int high = nums.length - 1; + while (low < high) { + int mid = low + (high - low) / 2; + if (nums[mid] <= nums[high]) { + high = mid; + } else { + low = mid + 1; + } + } + return nums[low]; + } + + public static int findMax(int[] nums) { + int low = 0; + int high = nums.length - 1; + while (low < high) { + int mid = low + (high - low) / 2; + if (nums[mid] >= nums[low]) { + low = mid; + } else { + high = mid - 1; + } + } + return nums[high]; + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q241/ExpressCompute.java b/code/src/main/java/com/raorao/leetcode/q241/ExpressCompute.java new file mode 100644 index 00000000..7bc3667f --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q241/ExpressCompute.java @@ -0,0 +1,54 @@ +package com.raorao.leetcode.q241; + +import java.util.ArrayList; +import java.util.List; + +/** + * 给表达式加括号. + * + * 分治法 + * + * @author Xiong Raorao + * @since 2018-08-21-17:01 + */ +public class ExpressCompute { + + public static void main(String[] args) { + String input = "2-1-1"; + List res = diffWaysToCompute(input); + res.forEach(e-> System.out.print(e+" ")); + } + + public static List diffWaysToCompute(String input) { + List items = new ArrayList<>(); + for (int i = 0; i < input.length(); i++) { + if (isChar(input, i)) { + List left = diffWaysToCompute(input.substring(0, i)); + List right = diffWaysToCompute(input.substring(i + 1)); + for (int l : left) { + for (int r : right) { + switch (input.charAt(i)) { + case '+': + items.add(l + r); + break; + case '-': + items.add(l - r); + break; + case '*': + items.add(l * r); + break; + } + } + } + } + } + if (items.size() == 0) { + items.add(Integer.parseInt(input)); + } + return items; + } + + private static boolean isChar(String input, int i) { + return input.charAt(i) == '+' || input.charAt(i) == '-' || input.charAt(i) == '*'; + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q347/TopKFrequent.java b/code/src/main/java/com/raorao/leetcode/q347/TopKFrequent.java new file mode 100644 index 00000000..30887497 --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q347/TopKFrequent.java @@ -0,0 +1,39 @@ +package com.raorao.leetcode.q347; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.TreeMap; +import java.util.stream.Collectors; + +/** + * 前K个出现频率最高的元素. + * + * @author Xiong Raorao + * @since 2018-08-21-8:55 + */ +public class TopKFrequent { + + public static void main(String[] args) { + int[] input = new int[] {1, 1, 1, 2, 2, 3}; + int k = 2; + List list = new TopKFrequent().topKFrequent(input, k); + list.forEach(e -> System.out.print(e + " ")); + } + + /** + * 对map的value进行降序排列,得到前K个就行了 + */ + public List topKFrequent(int[] nums, int k) { + List ret = new ArrayList<>(); + TreeMap map = new TreeMap<>(); + Arrays.stream(nums).forEach(e -> map.put(e, map.getOrDefault(e, 0) + 1)); + List> tmp = map.entrySet().stream() + .sorted((e1, e2) -> e2.getValue() - e1.getValue()).collect(Collectors.toList()); + for (int i = 0; i < k; i++) { + ret.add(tmp.get(i).getKey()); + } + return ret; + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q392/SubSequence.java b/code/src/main/java/com/raorao/leetcode/q392/SubSequence.java new file mode 100644 index 00000000..a008ec64 --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q392/SubSequence.java @@ -0,0 +1,44 @@ +package com.raorao.leetcode.q392; + +/** + * 判断是否为子序列. + * + * @author Xiong Raorao + * @since 2018-08-21-15:13 + */ +public class SubSequence { + + public static void main(String[] args) { + String s = "abc"; + String t = "ahbgdc"; + System.out.println(new SubSequence().isSubsequence2(s, t)); + } + + /** + * 贪心法,一个一个检索 + */ + public boolean isSubsequence(String s, String t) { + int index = -1; + for (char c : s.toCharArray()) { + index = t.indexOf(c, index + 1); + if (index == -1) { + return false; + } + } + return true; + } + + public boolean isSubsequence2(String s, String t) { + int is = 0; + int it = 0; + while (is < s.length() && it < t.length()) { + if (s.charAt(is) == t.charAt(it)) { + is++; + it++; + } else { + it++; + } + } + return is == s.length(); + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q605/PlantFlower.java b/code/src/main/java/com/raorao/leetcode/q605/PlantFlower.java new file mode 100644 index 00000000..32bb39a5 --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q605/PlantFlower.java @@ -0,0 +1,37 @@ +package com.raorao.leetcode.q605; + +/** + * 种植花朵. + * + * 问题描述;花朵之间至少需要一个单位的间隔,求解是否能种下 n 朵花。 + * + * @author Xiong Raorao + * @since 2018-08-21-11:40 + */ +public class PlantFlower { + + public static void main(String[] args) { + int[] input = new int[] {1, 0, 0, 0, 1}; + int n = 1; + System.out.println(new PlantFlower().canPlaceFlowers(input, n)); + } + + public boolean canPlaceFlowers(int[] flowerbed, int n) { + if (flowerbed == null || flowerbed.length == 0) { + return false; + } + int count = 0; // 统计最多能种多少棵 + for (int i = 0; i < flowerbed.length && count < n; i++) { + if (flowerbed[i] == 1) { + continue; + } + int pre = i == 0 ? 0 : flowerbed[i - 1]; + int next = i == flowerbed.length - 1 ? 0 : flowerbed[i + 1]; + if (pre == 0 && next == 0) { + count++; + flowerbed[i] = 1; + } + } + return count >= n; + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q665/NoneDecreasingArray.java b/code/src/main/java/com/raorao/leetcode/q665/NoneDecreasingArray.java new file mode 100644 index 00000000..7863596a --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q665/NoneDecreasingArray.java @@ -0,0 +1,29 @@ +package com.raorao.leetcode.q665; + +/** + * 判断是否为非递减数组. + * + * 题目描述:判断一个数组能不能只修改一个数就成为非递减数组。 + * + * @author Xiong Raorao + * @since 2018-08-21-15:44 + */ +public class NoneDecreasingArray { + + public boolean checkPossibility(int[] nums) { + int count = 0; // 修改次数 + for (int i = 1; i < nums.length && count < 2; i++) { + if (nums[i] >= nums[i - 1]) { + continue; + } + count++; + if (i > 1 && nums[i] < nums[i - 2]) { + nums[i] = nums[i - 1]; + } else { + nums[i - 1] = nums[i]; + } + } + return count < 2; + } + +} diff --git a/code/src/main/java/com/raorao/leetcode/q744/NextGreatestLetter.java b/code/src/main/java/com/raorao/leetcode/q744/NextGreatestLetter.java new file mode 100644 index 00000000..71838914 --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q744/NextGreatestLetter.java @@ -0,0 +1,24 @@ +package com.raorao.leetcode.q744; + +/** + * 寻找大于给定元素的最小元素. + * + * @author Xiong Raorao + * @since 2018-08-21-16:23 + */ +public class NextGreatestLetter { + + public char nextGreatestLetter(char[] letters, char target) { + int n = letters.length; + int l = 0, h = n - 1; + while (l <= h) { + int m = l + (h - l) / 2; + if (letters[m] <= target) { + l = m + 1; + } else { + h = m - 1; + } + } + return l < n ? letters[l] : letters[0]; + } +} diff --git a/code/src/main/java/com/raorao/leetcode/q763/SplitLetters.java b/code/src/main/java/com/raorao/leetcode/q763/SplitLetters.java new file mode 100644 index 00000000..c1378731 --- /dev/null +++ b/code/src/main/java/com/raorao/leetcode/q763/SplitLetters.java @@ -0,0 +1,48 @@ +package com.raorao.leetcode.q763; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 划分字母区间. + * + * 输入:划分字母区间来控制 + * + * @author Xiong Raorao + * @since 2018-08-21-10:53 + */ +public class SplitLetters { + + public static void main(String[] args) { + String input = "ababcbacadefegdehijhklij"; + List list = new SplitLetters().partitionLabels(input); + list.forEach(e -> System.out.print(e + " ")); + } + + public List partitionLabels(String S) { + List ret = new ArrayList<>(); + if (S == null || S.length() == 0) { + return ret; + } + Map map = new HashMap<>(); // 统计每个字符最后出现的位置 + for (int i = 0; i < S.length(); i++) { + map.put(S.charAt(i), i); + } + + int firstIndex = 0; + while (firstIndex < S.length()) { + int lastIndex = firstIndex; + for (int i = firstIndex; i < S.length() && i <= lastIndex; i++) { + int index = map.get(S.charAt(i)); + if (index > lastIndex) { + lastIndex = index; + } + } + ret.add(lastIndex - firstIndex + 1); + firstIndex = lastIndex + 1; + } + return ret; + } +} diff --git a/interview/note.md b/interview/note.md index 41e545ef..8fddd19c 100644 --- a/interview/note.md +++ b/interview/note.md @@ -37,6 +37,7 @@ Java后端开发(大数据、分布式应用等) 招银网络 | 8.7(内推) | 8.20 | 小米科技 | 8.20(柚子妹内推) | 8.20 | 时间不详 京东 | 8.4 | 8.20 |
  • 简历截止:8.30
  • 笔试时间 9.9
  • 面试时间 9.16-9.20
  • +微众银行| 8.20 | 8.20 | # 2 复习内容