查找算法(Java)
目录
一.定义
二.分类
三.线性查找
原理:
思路分析
代码实现
例题实践
1.两数之和
方法一:暴力穷举法
思路分析
代码实现
方法二:创建哈希表
思路分析
代码实现
2.移动零
思路分析
代码实现
四.二分查找
原理:
思路分析
例题实践
思路分析
代码实现
一.定义
查找算法是在数据集合中寻找满足某种条件的数据元素的过程。
二.分类
在Java中我们常见的查找算法有四种:
1.顺序(线性)查找
2.二分查找/折半查找
3.插值查找
4.斐波拉契查找
今天我们讲前两个查找算法
三.线性查找
原理:
线性查找是一种简单的查找算法,它从数据结构的一端开始,逐个检查每个元素,直到找到所需的元素或搜索到数据结构的另一端。
思路分析
1.从第一个元素开始,逐个与要查找的元素进行比较;如果当前元素不是要查找的元素,则继续向后查找;
2.如果找到要查找的元素,则返回该元素的位置;如果查找到数据结构的末端仍未找到要查找的元素,则返回一个标识(如-1),表示查找失败。
代码实现
public class LookupAlgorithm
{//线性查找方法public static int linearSearch(int[] arr, int key){//循环遍历数组,找到要查找的值for(int i = 0; i < arr.length; i++){if(arr[i] == key){return i;}}return -1;//找不到返回-1}public static void main (String[] args){int[] arr = {5,6,9,8,6,11,7,56,89};//现在查找56这个元素int index=linearSearch(arr,56);if(index == -1){System.out.println("未找到该元素");}else{System.out.println("该元素的下标为:"+index);}}
}
例题实践
1.两数之和
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。你可以按任意顺序返回答案。
方法一:暴力穷举法
思路分析
我们可以直接使用嵌套循环,外循环从第一个索引开始,内循环外循环开始的索引处+1开始,一直循环到找出目标值的两个整数
代码实现
//暴力穷举public static int[] TwoValue(int[] arr, int key){//先定义一个数组,来存储找到的两个值的索引int[] result=new int[2];//开始遍历外循环中的每个元素for(int i = 0; i < arr.length; i++){//内循环从外循环的i位置处的下一个开始遍历for(int j = i+1; j < arr.length; j++){if(arr[i] +arr[j]==key){result[0]=i;result[1]=j;return result;}}}return result;}
方法二:创建哈希表
关于哈希表的知识点,推荐这篇文章:
https://blog.csdn.net/duan19920101/article/details/51579136?fromshare=blogdetail&sharetype=blogdetail&sharerId=51579136&sharerefer=PC&sharesource=2401_87935803&sharefrom=from_link
思路分析
利用哈希表,将所求差值放入哈希表中,直到找到两个可以匹配成功的值
代码实现
//方法二:利用哈希表public static int[] ToSum(int[] arr, int key){//创建哈希表Map<Integer, Integer> hashMap=new HashMap<>();//遍历数组for(int i = 0; i < arr.length; i++){//计算当前元素与目标值的差值int complement=key-arr[i];//检查哈希表中是否已存在这个差值作为键,如果存在,既找到了目标的两个数if(hashMap.containsKey(complement)){return new int []{hashMap.get(complement),i};}//如果哈希表不存在这个差值,就将当前元素arr[i]及其索引存入哈希表hashMap.put(arr[i], i);}return new int [] {};}
2.移动零
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
思路分析
代码实现
//移动零public static void moveZeroes(int[] nums) {// 定义一个指针,用于指向当前非零元素应该放置的位置int nonZeroIndex = 0;// 遍历数组for (int i = 0; i < nums.length; i++) {// 如果当前元素不为0if (nums[i] != 0) {// 将该非零元素放置到nonZeroIndex指向的位置nums[nonZeroIndex] = nums[i];// nonZeroIndex后移一位,为下一个非零元素做准备nonZeroIndex++;}}// 当遍历完数组后,nonZeroIndex之后的位置都应该填充为0for (int i = nonZeroIndex; i < nums.length; i++) {nums[i] = 0;}}
四.二分查找
原理:
搜索过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜索过程结束;
如果某一特定元素大于或小于中间元素,则在数组大于或小于中间元素的那一半中查找,而且此过程可以递归进行,直到找到要查找的元素,或者整个数组范围被搜索完。
思路分析
1.首先确定该数组的中间的下标 mid=(left+right)/2
2.然后让需要查找的数findVal和arr[mid]比较
2.1 findVal>arr[mid],说明你要查找的数在mid的右边,因此需要递归的向右查找
2.2 findVal<arr[mid],说明你要查找的数在mid的左边,因此需要递归的向左查找
2.3 findVal==arr[mid]说明找到,就返回索引下标
代码实现
//二分查找public static int binarySearch(int[] arr, int left, int right, int findVal){// 当left >right时,说明递归整个数组, 没有找到if(left>right){return -1;}int mid = (left + right)/2;int midVal = arr[mid];if(findVal<midVal){return binarySearch(arr, left, mid - 1, findVal);//向左递归} else if ( findVal>midVal) //向右递归{return binarySearch(arr, mid + 1, right, findVal);}else{return mid;//返回索引}}
例题实践
搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n)
的算法。
思路分析
根据题目可知,本题要用二分查找法
代码实现
//搜索插入位置public int searchInsert(int[] nums, int target) {int left=0;//初始化左边界的第一个位置int right=nums.length-1;//初始化数组的最后一个位置//当左边界小于右边界时继续循环while (left<=right){int mid=(left+right)/2;//找到中间值if(nums[mid]==target){return mid;//如果中间位置等于目标值,则返回} else if (nums[mid]>target) {right=mid-1;//中间值大于目标值,在左半部分查找}else{left=mid+1;//中间值小于目标值,则在右半部分}}return left;//返回左边界为插入值}