全网推广开户,网站网络优化服务,谷歌seo软件,龙岩有什么兼职可以做文章目录 引言复习新作在排序数组中查找元素的第一个和最后一个位置个人实现参考实现 搜索旋转排序数组个人实现参考实现 总结 引言
复习
新作
在排序数组中查找元素的第一个和最后一个位置
题目链接 注意
非递减序列》元素是递增或者相等#xff0c;并不是严格递增的找到… 文章目录 引言复习新作在排序数组中查找元素的第一个和最后一个位置个人实现参考实现 搜索旋转排序数组个人实现参考实现 总结 引言
复习
新作
在排序数组中查找元素的第一个和最后一个位置
题目链接 注意
非递减序列》元素是递增或者相等并不是严格递增的找到给定目标值在数组中开始的位置和结束的位置时间复杂度是logn
个人实现
这道题就是典型的二分查找的但是需要知道你背的模板的特点的——“左加大右减小”
class Solution {public int[] searchRange(int[] nums, int tar) {//define result vectorint[] res {-1,-1};if(nums.length 0) return res;// binary findint m nums.length;int l 0,r m - 1;while(l r){int mid (l r) 1;if(nums[mid] tar) r mid;else l mid 1;}// System.out.println(l);// judge whether find the valueif(nums[l] ! tar) return res;// the value is the first bigger numwhile(l 1 nums[l - 1] tar) l --;while(r 1 m nums[r 1] tar) r;res[0] l;res[1] r;return res;}
}写是写完了这里得去看一下Java中数组的操作这里整的有点不熟悉导致很多操作和C弄混了
// create the fixed length array
int[] fixedArray new int[5];
int[] ifxedArray {1,2,3,4,5};参考实现
这里是使用了两个不同的模板一个确定左边界还有一个是确定有边界的。具体两个模板如下
确定左边界
int l 0,r m-1;
while(l r){int mid (r l) 1;if(nums[mid] tar) r mid;else l mid 1;
}
// l is the left edge 确定右边界
int l 0,r m - 1;
while(l r){int mid (l r 1) 1; // 仅仅针对右边界防止死循环if(nums[mid] tar) l mid;else r mid - 1;
}最终实现如下
class Solution {public int[] searchRange(int[] nums, int tar) {//define result vectorint[] res {-1,-1};if(nums.length 0) return res;// binary findint m nums.length;int l 0,r m - 1;while(l r){int mid (l r) 1;if(nums[mid] tar) r mid;else l mid 1;}// judge whether find the valueif(nums[l] ! tar) return res;res[0] l;// the value is the first bigger numl l ;r m - 1;while(l r){int mid (l r 1) 1;System.out.println(mid);if(nums[mid] tar) l mid;else r mid - 1;}res[1] r;return res;}
}搜索旋转排序数组
题目链接 注意数组严格单调递增数组不为空数组的值不会存在溢出的情况
个人实现
这道题是一个二分查找但是需要转换坐标将当前坐标转换为未旋转之前的坐标或者是对其进行分段二分然后查找目标值。现在有一个问题无论是哪种方法都需要知道在哪里进行的反转如果完整遍历一次对应元素时间复杂度就是On肯定超时现在就是想着通过单调递增的方式尽量快速确定反转的地方。找到反转点 元素与元素 之间只有严格的大于或者小于关系往后遍历就是一定大于往前遍历一定小于异常就是说明旋转点就在这一段 找到target就是使用二分查找
class Solution {public int binFind(int[] nums,int l,int r,int tar){while(l r){int mid (l r) 1;if(nums[mid] tar) r mid;else l mid 1;}return l;}public int search(int[] nums, int tar) {int m nums.length ;// handle the edge situationif(m 1) return nums[0] tar?0:-1;// find the reverse pointint len m / 2;int revP 0;while(len 1){if(nums[revP] nums[revP len - 1]){revP len;}else{len / 2;}}// find the target int res;System.out.println(revP);if(tar nums[0]){res binFind(nums,0,revP,tar);}else{System.out.println(last);res binFind(nums,revP 1 ,m - 1,tar);}System.out.println(res);// judge the result if(nums[res] tar) return res;else return -1;}
}这里只能通过部分样例
因为第一个是总是能够算准的但是第二个不好处理不应该呀第二个总是越界出现各种各样的问题 反转点在第一个元素的位置反转点在最后一个元素的位置仅有两个元素如何进行判定
但是就是会出现异常难受
参考实现
这里整体的思路和我的一样先找划分点然后二分查找。
这里有一个很巧妙的地方就是一开始根据条件确定旋转点类似的二分都可以用同样的思路
基本想法和我的是一样的都是通过等分对应区间长度然后在进行比较划分只不过他的套用模板可靠性更高 具体实现代码如下
class Solution {public int search(int[] nums, int tar) {int m nums.length ;// handle the edge situationif(m 1) return nums[0] tar?0:-1;// find the reverse pointint l 0 ,r m - 1;while(l r){int mid (l r 1) 1;if(nums[mid] nums[0]) l mid;else r mid - 1;}// find the target if(tar nums[0] ){l 0;}else{l l 1;r m - 1; }while(l r){int mid (l r) 1;if(nums[mid] tar) r mid;else l mid 1;}// judge the result if(nums[r] tar) return r;else return -1;}
}对于模板的进一步总结 左加大返回右右减小返回左
// 方案一右边界
int l 0,r m - 1;
while(l r){int mid (rl)1;if(nums[mid] tar) r mid;else l mid 1;
}
return r;// 方案二左边界
int l 0,r m - 1;
while(l r){int mid (rl)1;if(nums[mid] tar) l mid;else r mid - 1;
}
return l;总结
昨天是纯纯摆烂了主要是最近的状态属实不是很好学不进去昨晚上看了一会电视聊了会天看了会书然后十二点就睡了早上起来挺早的背了会书现在开始刷算法进度还行调整一下效果还是很好的投了字节的另外一个部门然后居然还给我面试了这周五继续加油