diff --git a/.gitignore b/.gitignore index 3cd2d05..a99dd7a 100644 --- a/.gitignore +++ b/.gitignore @@ -27,11 +27,13 @@ *.tar *.zip *.via +*.iml *.tmp *.err *.log # OS generated files # -.DS_Store +/.idea +.DS_Store .DS_Store? ._* .Spotlight-V100 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1 @@ + diff --git a/pom.xml b/pom.xml index c0e565f..bde2feb 100644 --- a/pom.xml +++ b/pom.xml @@ -4,11 +4,11 @@ 4.0.0 1.0.0 - java_study + java-study 0.0.1-SNAPSHOT jar - java_study + java-study http://maven.apache.org @@ -182,6 +182,13 @@ 2.3.0 + + + com.google.guava + guava + 27.1-jre + + diff --git a/src/main/java/com/pancm/arithmetic/jzoffer/DuplicateNumberInArray.java b/src/main/java/com/pancm/arithmetic/jzoffer/DuplicateNumberInArray.java new file mode 100644 index 0000000..8f7734b --- /dev/null +++ b/src/main/java/com/pancm/arithmetic/jzoffer/DuplicateNumberInArray.java @@ -0,0 +1,147 @@ +package com.pancm.arithmetic.jzoffer; + +/** + * https://www.nowcoder.com/practice/623a5ac0ea5b4e5f95552655361ae0a8?tpId=13&tqId=11203&tPage=1&rp=1&ru=/ta/coding-interviews&qru=/ta/coding-interviews/question-ranking + * + * @description: + * 3.数组中的重复数字 + * 在一个长度为 n 的数组里的所有数字都在 0 到 n-1 的范围内。 + * 数组中某些数字是重复的,但不知道有几个数字是重复的,也不知道每个数字重复几次。 + * 请找出数组中任意一个重复的数字。 + * + * @author: Zhoust + * @date: 2019/04/28 10:58 + * @version: V1.0 + */ +public class DuplicateNumberInArray { + + /** + * 一种简单的实现思路,借助外部数组保存 numbers 中每个值的出现次数,即 numbers 中的值作为数组 array 的下标。 + * 题目中说了长度为 n 的数组中每个值都在 0 到 n-1 范围内,因此遍历数组 numbers 存入对应的 array 不会出现数组下标越界的问题 + * @param numbers + * @param length numbers 数组的长度 + * @param duplication (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation; + * 这里要特别注意~返回任意重复的一个,赋值duplication[0] + * @return true if the input is valid, and there are some duplications in the array number, otherwise false + */ + public boolean duplicate(int[] numbers, int length, int[] duplication) { + if (numbers == null) { + return false; + } + boolean result = false; + int[] array = new int[length]; + for (int i = 0; i < length; i++) { + if (++array[numbers[i]] > 1 && !result) { + result = true; + duplication[0] = numbers[i]; + } + } + return result; + } + + /** + * 先排序,然后找到排序后数组中第一个重复的数字(主要就是练习一下快排) + * @param numbers + * @param length + * @param duplication + * @return + */ + public boolean sortThenFindFirstDuplicateNumber(int[] numbers, int length, int[] duplication) { + if (numbers == null) { + return false; + } + quickSort(numbers, 0, length-1); + int temp = numbers[0]; + boolean result = false; + + for (int i = 1; i < length; i++) { + if (numbers[i] == temp) { + result = true; + duplication[0] = temp; + break; + } + temp = numbers[i]; + } + return result; + } + + /** + * 将值为 i 的元素调整到下标为 i 的位置,如果该位置上的数已经等于 i 了,就说明 i 已经重复了 + * @param numbers + * @param length + * @param duplication + * @return + */ + public static boolean jz(int[] numbers, int length, int[] duplication) { + for (int i = 0; i < length; i++) { + //第 i 个位置上的数 numbers[i] 若不与下标 i 相等,就把 numbers[i] 放到下标为 numbers[i] 的位置 + while (numbers[i] != i) { + //在交换位置之前还要检查 numbers[i] 位置上的数字是否已经是 numbers[i],如果是就已经找到了重复的数字 + if (numbers[numbers[i]] == numbers[i]) { + duplication[0] = numbers[i]; + //注意这里不是 break + return true; + } + + //交换下标为 i、numbers[i] 两个位置上的数字(保证下标为 numbers[i] 的位置,放置的数字是 numbers[i]) + swap(numbers, i, numbers[i]); + } + } + return false; + } + + /** + * 交换下标为 i、j 的两个数 + * @param numbers + * @param i + * @param j + */ + public static void swap(int[] numbers, int i, int j) { + int swap = numbers[i]; + numbers[i] = numbers[j]; + numbers[j] = swap; + } + + /** + * 快排 + * @param array + * @param length + */ + @SuppressWarnings("all") + public static void quickSort(int[] array, int low, int high) { + //这里必须首先限制 low temp && h > l) { + h--; + } + array[l] = array[h]; + while (array[l] <= temp && l < h) { + l++; + } + array[h] = array[l]; + } + array[l] = temp; + quickSort(array, low, h-1); + quickSort(array, l+1, high); + } + } + + public static void main(String[] args) { + int[] result = new int[1]; + jz(new int[]{2,4,2,1,4}, 5, result); + System.out.println(result[0]); +// int[] d = new int[1]; +// jz(new int[]{2,1,3,0,4}, 5, d); +// int[] array = new int[]{1,4,4,4,12,78,8,45,67,39,20,90,65,34,34,6,7,88,9,1,-3,-88,-2}; + int[] array = new int[]{2,4,3,1,4}; + quickSort(array, 0, array.length-1); + for (int i = 0; i < array.length; i++) { + System.out.println(array[i]); + } + + } + +} \ No newline at end of file diff --git a/src/main/java/com/pancm/arithmetic/jzoffer/package-info.java b/src/main/java/com/pancm/arithmetic/jzoffer/package-info.java new file mode 100644 index 0000000..5a7d751 --- /dev/null +++ b/src/main/java/com/pancm/arithmetic/jzoffer/package-info.java @@ -0,0 +1,7 @@ +/** + * @description: 剑指 Offer 中的题目 + * @author: Zhoust + * @date: 2019/04/28 10:57 + * @version: V1.0 + */ +package com.pancm.arithmetic.jzoffer; \ No newline at end of file