数组基础知识点不多说,都还记得
704. 二分查找
题目链接:https://leetcode.cn/problems/binary-search/
文章讲解:https://programmercarl.com/0704.%E4%BA%8C%E5%88%86%E6%9F%A5%E6%89%BE.html
视频讲解:https://www.bilibili.com/video/BV1fA4y1o715
状态:做出来了
思路
二分查找,因为数组为有序数组,同时数组中无重复元素。
注意事项
1.边界条件【左闭右闭、左闭右开两种写法】
是while(left < right)
还是 while(left <= right)
?
可以考虑只有一个元素的情况
是right = middle
呢,还是要right = middle - 1
?
开区间默认是取不到的坐标,所以不用减一,闭区间默认是取到的实际坐标,所以需要减一(第一次写的时候犯错了)
2.防止溢出的写法
int middle = left + ((right - left) / 2);//等同于(left + right)/2
3.注意二分查找的条件:有序、无重复
代码一【左闭右闭】(我的解法)
class Solution {
public int search(int[] nums, int target) {
int left=0;
// 右闭条件
int right=nums.length-1;
// 当left==right,区间依然有效,所以用 <=,可以假设就一个元素的情况
while(left<=right){
// 防止溢出
int mid=left+(right-left)/2;
if(nums[mid]==target)
return mid;
else if (nums[mid]<target){
// target 在左区间,所以[left, middle - 1]
left=mid+1;
}
else{
// 右闭条件:target 在左区间,所以[left, middle - 1]
right=mid-1;
}
}
return -1;
}
}
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
代码二【左闭右开】
class Solution {
public int search(int[] nums, int target) {
int left=0;
// 右开条件
int right=nums.length;
// 当left==right,区间无效,所以用 <,可以假设就一个元素的情况
while(left<right){
// 防止溢出
int mid=left+(right-left)/2;
if(nums[mid]==target)
return mid;
else if (nums[mid]<target){
// 同右闭
left=mid+1;
}
else{
// 右开条件:right默认是开区间
right=mid;
}
}
return -1;
}
}
- 时间复杂度:O(log n)
- 空间复杂度:O(1)
27. 移除元素
题目链接:https://leetcode.cn/problems/remove-element/
文章讲解:https://programmercarl.com/0027.%E7%A7%BB%E9%99%A4%E5%85%83%E7%B4%A0.html
视频讲解:https://www.bilibili.com/video/BV12A4y1Z7LP
状态:做出来了
思路
双指针里的左右指针
注意事项
1.right要左移到第一个值不为val的位置,提高运算效率
//将right移到从右数第一个值不为val的位置
while(right >= 0 && nums[right] == val) right--;
代码一【左右指针】(我的解法)
//相向双指针法
class Solution {
public int removeElement(int[] nums, int val) {
int left = 0;
int right = nums.length - 1;
//将right移到从右数第一个值不为val的位置
while(right >= 0 && nums[right] == val) right--;
while(left <= right) {
if(nums[left] == val) { //left位置的元素需要移除
//将right位置的元素移到left(覆盖),right位置移除
nums[left] = nums[right];
right--;
}
left++;
while(right >= 0 && nums[right] == val) right--;
}
return left;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
代码二【快慢指针】(没想出来)
class Solution {
public int removeElement(int[] nums, int val) {
// 快慢指针
int slowIndex = 0;
//快指针扫描全表,作为判定标准,慢指针定位val值的位置
for (int fastIndex = 0; fastIndex < nums.length; fastIndex++) {
if (nums[fastIndex] != val) {
nums[slowIndex] = nums[fastIndex];
slowIndex++;
}
}
return slowIndex;
}
}
- 时间复杂度:O(n)
- 空间复杂度:O(1)
代码三【暴力解法】
略
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
977.有序数组的平方
题目链接:https://leetcode.cn/problems/squares-of-a-sorted-array/
文章讲解:https://programmercarl.com/0977.%E6%9C%89%E5%BA%8F%E6%95%B0%E7%BB%84%E7%9A%84%E5%B9%B3%E6%96%B9.html
视频讲解: https://www.bilibili.com/video/BV1QB4y1D7ep
状态:做出来了
思路
双指针的左右指针,因为数组有序,两端的平方是极大值
代码一【左右指针】(我的解法)
class Solution {
public int[] sortedSquares(int[] nums) {
int l = 0;
int r = nums.length - 1;
int[] res = new int[nums.length];
int j = nums.length - 1;
while(l <= r){
if(nums[l] * nums[l] > nums[r] * nums[r]){
res[j--] = nums[l] * nums[l++];
}else{
res[j--] = nums[r] * nums[r--];
}
}
return res;
}
}
- 时间复杂度:O(n^2)
- 空间复杂度:O(1)
代码二【暴力求解】
思路:先平方再排序(调用快排函数)
代码略
- 时间复杂度:O(nlogn)
- 空间复杂度:O(logn)-O(n)