牛客算法题_查找
1. 排序数据找出某个值(重要)
思路:
1. 数组先简单的判断, 然后调用查询方法
2. 定义一个可以递归的方法,按照区间进行查找
public int search (int[] nums, int target) {if(nums.length == 1 && target == nums[0]){return 0;}if(nums.length == 1 && target != nums[0]){return -1;}return searchTarget(nums, 0, nums.length - 1, target);}public int searchTarget(int[] nums, int left, int right, int target) {if (left > right) {return -1;}int mid = (right - left) / 2 + left;if(nums[mid ] == target){return mid;}else if(target > nums[mid ]){return searchTarget(nums, mid+1, right, target);}else if(target < nums[mid ]){return searchTarget(nums, left, mid-1, target);}else{return -1;}}
2. 排序的二维数组判断某个值存在(重要)
思路:
从左下角元素开始查找,,右边元素是比这个元素大,上边是的元素比这个元素小。于是,target比这个元素小就往上找,比这个元素大就往右找。如果出了边界,则说明二维数组中不存在target元素。
public boolean Find(int target, int[][] array) {if (array == null) {return false;}int m = array.length;int n = array[0].length;// 从左下角元素往上查找,右边元素是比这个元素大,上边是的元素比这个元素小。于是,target比这个元素小就往上找,比这个元素大就往右找。如果出了边界,则说明二维数组中不存在target元素。for (int i = m - 1, j = 0; i >= 0 && j < n; ) {if(target == array[i][j]){return true;}else if(target < array[i][j]){i--;}else if(target > array[i][j]){j++;}}return false;}
3. 判断数组峰值
思路:当前值与左右值比较,注意假设 nums[-1] = nums[n] = −∞, 注意左右头节点的比较。
public int findPeakElement (int[] nums) {if(nums == null){return -1;}if(nums.length == 1){return 0;}Boolean lcompare;Boolean rcompare;for(int i = 0; i < nums.length; i++){if(i == 0){lcompare = true;}else{lcompare = nums[i] > nums[i-1];}if(i == nums.length -1 ){rcompare = true;}else{rcompare = nums[i] > nums[i+1];}if(lcompare && rcompare){return i;}}return -1;// write code here}
4. 数组旋转后求最小值(重要)
思路:如果顺序比较,方法简单,但是不满足时间复杂度:O(logn)的要求,所以还是得折半查找。
1. min < nums[mid], 往右找
2. min > nums[mid], 往左找
3. min = nums[mid], 两边都得找,取最小值
4. 注意判断left 和 right边界值
public int minNumberInRotateArray(int[] nums) {if (nums.length == 1) {return nums[0];}int min = nums[0];return minValue(nums, min, 1, nums.length - 1);// write code here}public int minValue(int[] nums, int min, int left, int right) {if (left > right) {return min;}if(left == right){return min > nums[left]? nums[left]: min;}int mid = (right - left) / 2 + left;if (min < nums[mid]) {return minValue(nums, min, mid + 1, right);} else if (min > nums[mid]) {min = nums[mid];return minValue(nums, min, left, mid - 1);} else{// 左int x = minValue(nums, min, left, mid - 1);// yint y = minValue(nums, min, mid + 1, right);return x > y ? y : x;}}
5. 版本号比较
版本号,比如1.02.11,2.14.4等等
比较规则:
一. 比较版本号时,请按从左到右的顺序依次比较它们的修订号。比较修订号时,只需比较忽略任何前导零后的整数值。比如"0.1"和"0.01"的版本号是相等的
二. 如果版本号没有指定某个下标处的修订号,则该修订号视为0。例如,"1.1"的版本号小于"1.1.1"。因为"1.1"的版本号相当于"1.1.0",第3位修订号的下标为0,小于1
三. version1 > version2 返回1,如果 version1 < version2 返回-1,不然返回0.
思路:
1. 字符串按照.分割, 注意这里要用转义字符
2. 逐个比较
3. 超出长度位置,和0比较,注意i++ 或者j++
public int compare(String version1, String version2) {String[] array1 = version1.split("\\.");String[] array2 = version2.split("\\.");int i = 0;int j = 0;for(; i< array1.length && j < array2.length;i++, j++ ){int x1 = Integer.valueOf(array1[i]);int x2 = Integer.valueOf(array2[j]);if(x1 > x2){return 1;}if(x1 < x2){return -1;}}if(i <array1.length ){while (i <array1.length ){int x1 = Integer.valueOf(array1[i]);if (x1 > 0) {return 1;}if(x1 < 0){return -1;}// 不要忘了这句i++;}return 0;}if(j <array2.length ){while (j <array2.length ){int x2 = Integer.valueOf(array2[j]);if (x2 > 0) {return -1;}if(x2 < 0){return 1;}// 不要忘了这句j++;}return 0;}// write code herereturn 0;}