逐个遍历,判断是否是待查找的元素
public int search(int[] array,int key){
for(int i=0;i<array.length;i++){
if(array[i]==key){
return i;
}
}
return -1;
}
有序数组可用,可作为模板记忆,注意边界
public int binarySearch(int[] array,int key,int low,int high){
while (low<= high){
int mid = low+((high-low)>>1);
if(array[mid]==key){
return mid;
}else if(array[mid]>key){
high = mid - 1;
}else if(array[mid]<key){
low = mid + 1;
}
}
return -1;
}
有序数组可用,可作为模板记忆,注意边界
public int binarySearch(int[] array,int key,int low,int high){
if(low<=high){
int mid = low+((high-low)>>1);
if(array[mid]==key){
return mid;
}else if(array[mid]>key){
return binarySearch(array,key,low,mid-1);
}else if(array[mid]<key){
return binarySearch(array,key,mid+1,high);
}
}
return -1;
}
基于模板找到元素后,继续向前遍历,找到等于待查找元素在数组中首次出现的位置,如果元素过多,也可使用二分查找方式继续查找
public int binarySearchRe(int[] array, int key, int low, int high) {
while (low <= high) {
int mid = low + ((high - low) >> 1);
if (array[mid] == key) {
while (mid >= 0 && array[mid] == key) {
mid--;
}
return mid + 1;
} else if (array[mid] > key) {
high = mid - 1;
} else if (array[mid] < key) {
low = mid + 1;
}
}
return -1;
}
基于模板找到元素后,继续向前、后遍历,找到等于待查找元素在数组中首次出现的位置和最后出现的位置,如果元素过多,也可使用二分查找方式继续查找
public int[] searchRange(int[] nums, int target) {
return binarySearch(nums,target,0,nums.length-1);
}
public int[] binarySearch(int[] nums,int target,int low,int high){
int[] res = new int[]{-1,-1};
while(low<=high){
int mid = low + ((high-low)>>1);
if(nums[mid]==target){
int left = mid;
while(left>=0&&nums[left]==target){
left--;
}
int right = mid;
while(right<nums.length&&nums[right]==target){
right++;
}
res[0] = left+1;
res[1] = right-1;
return res;
}else if(nums[mid]>target){
high = mid-1;
}else if(nums[mid]<target){
low = mid+1;
}
}
return res;
}
注意山脉的判断条件,高于两侧数据,递增顺序在左侧,递减顺序在右侧
public int peakIndexInMountainArray(int[] arr) {
int high = arr.length-2;
int low = 1;
while(low <= high){
int mid = low+((high-low)>>1);
if(arr[mid]>arr[mid-1] && arr[mid]>arr[mid+1]){
return mid;
}else if(arr[mid]>arr[mid-1] && arr[mid]<arr[mid+1]){
low = mid+1;
}else if(arr[mid]<arr[mid-1] && arr[mid]>arr[mid+1]){
high = mid - 1;
}
}
return -1;
}
使用二分查找模板,边界值通过测试样例确定
public int findMin(int[] nums) {
int low = 0;
int high = nums.length - 1;
while(low<high){
int mid = low+((high-low)>>1);
if(nums[mid]>nums[high]){
low = mid+1;
}else if(nums[mid]<nums[high]){
high = mid;
}
}
return nums[low];
}
使用二分查找模板,边界值通过测试样例确定
public int missingNumber(int[] array){
int high = array.length;
int low = 0;
while (low<=high){
int mid = low + ((high - low)>>1);
if(array[mid] == mid){
low = mid+1;
}else{
high = mid - 1;
}
}
return low;
}
使用二分查找模板,边界值通过测试样例确定
public int mySqrt(int x) {
int low = 1;
int high = x;
while(low <= high){
int num = low + ((high-low)>>1);
if(x/num == num){
return num;
}else if(x/num>num){
low = num + 1;
}else{
high = num - 1;
}
}
return high;
}
二分查找与二叉树的结合,先判断根节点,根据根节点与待查找值的情况判断在左子树或者右子树查找
public TreeNode searchBST(TreeNode root, int val) {
if(root==null){
return null;
}else if(root.val == val){
return root;
}else if(root.val<val){
return searchBST(root.right,val);
}else if(root.val>val){
return searchBST(root.left,val);
}
return null;
}
限定low和high两个范围进行验证,验证左右子树时,根据根节点的值更新low和high
public boolean isValidBST(TreeNode root) {
long low = Long.MIN_VALUE;
long high = Long.MAX_VALUE;
return isValidBST(root,low,high);
}
public boolean isValidBST(TreeNode root,long low,long high){
if(root==null){
return true;
}
if(root.val<=low || root.val >=high){
return false;
}
return isValidBST(root.left,low,root.val)&&isValidBST(root.right,root.val,high);
}
每次选择中间值作为根节点,再通过左右两个序列创建左右子树
public TreeNode sortedArrayToBST(int[] nums) {
return sortedArrayToBST(nums,0,nums.length-1);
}
public TreeNode sortedArrayToBST(int[] nums,int left,int right){
if(left>right){
return null;
}
int mid = left+((right-left)>>1);
TreeNode root = new TreeNode(nums[mid]);
root.left = sortedArrayToBST(nums,left,mid-1);
root.right = sortedArrayToBST(nums,mid+1,right);
return root;
}
快速排序模板1
public void quickSort(int[] array, int left, int right) {
if(left<right){
int pivot = array[left];
int i = right + 1;
for (int j = right; j > left; j++) {
if (array[j] > pivot) {
i--;
int temp = array[j];
array[j] = array[i];
array[i] = temp;
}
}
int pivotIndex = i - 1;
int temp = array[left];
array[left] = array[pivotIndex];
array[pivotIndex] = temp;
quickSort(array,left,pivotIndex-1);
quickSort(array,pivotIndex+1,right);
}
}
快速排序模板2
public void quickSort(int[] array, int left, int right) {
if (left < right) {
int pivot = array[right];
int i = left - 1;
for (int j = left; j < right; j++) {
if (array[j] < pivot) {
i++;
int temp = array[i];
array[i] = array[j];
array[j] = temp;
}
}
int pivotIndex = i + 1;
int temp = array[pivotIndex];
array[pivotIndex] = array[right];
array[right] = temp;
quickSort(array, left, pivotIndex - 1);
quickSort(array, pivotIndex + 1, right);
}
}
快速排序模板3
public static void quickSort(int[] array, int start, int end) {
if (start >= end) {
return;
}
int left = start;
int right = end;
int mid = (left + right) / 2;
int pivot = array[mid];
while (left <= right) {
while (left <= right && array[left] < pivot) {
left++;
}
while (left <= right && array[right] > pivot) {
right--;
}
if (left <= right) {
int temp = array[left];
array[left] = array[right];
array[right] = temp;
left++;
right--;
}
}
quickSort(array, start, right);
quickSort(array, left, end);
}
归并排序模板
public void mergeSort(int[] array, int start, int end, int[] temp) {
//2.直至每个序列只包含一个元素,停止划分
if (start >= end) {
return;
}
//1.从中间开始,每次划分为两个序列
mergeSort(array, start, (start + end) / 2, temp);
mergeSort(array, (start + end) / 2 + 1, end, temp);
//3。进行有序数组的合并
merge(array, start, end, temp);
}
public void merge(int[] array, int start, int end, int[] temp) {
//找到序列中点
int mid = (start + end) / 2;
//left遍历左边的序列
int left = start;
//right遍历右边的序列
int right = mid + 1;
//index遍历临时数组,存储合并结果
int index = 0;
//两个序列均从起点到终点进行遍历
while (left <= mid && right <= end) {
//将两个序列中较小的元素放入临时数组中
if (array[left] < array[right]) {
temp[index++] =array[left++];
}else {
temp[index++] =array[right++];
}
}
//此时仅剩一个序列未遍历结束,直接赋值
while (left <= mid){
temp[index++] =array[left++];
}
while (right<=end){
temp[index++] =array[right++];
}
//将归并的结果拷贝到原数组
for (int i=start;i<=end;i++){
array[i] = temp[i];
}
}
数组中第K大的数的问题可以通过数组排序解决,根据题目中给定的时间、空间复杂福选择合适的排序算法