数组是非常基础的数据结构,关于数组算法的题目一般在思维上不难,但是仍要自己动手实现才能发现细节问题
数组是存放在连续内存空间上的相同类型数据的集合
- 数组下标是从0开始的
- 不同于链表,数组内存地址是连续的
- 数组的元素不能进行删除,只能覆盖
- 如删除中间元素需把后面的所有元素向前做移动操作
要求
给定一个n个元素有序的(升序)整型数组nums和一个目标值target,写一个函数搜索nums中的target,如果目标值存在返回下标,否则返回-1。
示例:
输入: nums = [-1,0,3,5,9,12], target = 9输出: 4解释: 9 出现在 nums 中并且下标为 4输入: nums = [-1,0,3,5,9,12], target = 2输出: -1解释: 2 不存在 nums 中因此返回 -1
解法
暴力解法
for循环遍历数组,找出数组中的target值并返回下标,不做过多解释
class Solution {public int search(int[] nums, int target) {for(int i = 0; i < nums.length; i++){if(nums[i] == target){return i;}}return -1;}}
二分查找
题目提到数组按照升序排列,并且数组中无重复元素,这些都是使用二分查找的前提条件
利用数组排列,每次取值选取中间下标的值快速缩短查找范围
class Solution {public int search(int[] nums, int target) {// 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算if (target < nums[0] || target > nums[nums.length - 1]) {return -1;}int left = 0;int right = nums.length - 1;int middle = (left + right) / 2;// int middle = left + (right - left >> 1); 防止left+right溢出while(left <= right){//思考终止条件 left < right 以及 nums[middle] != target是否可行,可以试着写下不同解法if(nums[middle] == target){return middle;}else if(nums[middle] < target){left = middle + 1;middle = (left + right) / 2;}else{right = middle - 1;middle = (left + right) / 2;}}return -1;}}
学有余力的同学可以分析一下最优情况、最坏情况、一般情况下的时间、空间复杂度
