目录
704.二分查找
1.解题思路
数组有排序,我们先确定一个循环的进入条件和结束条件,该题存在两种情况,及右边界的选择:
左闭右闭:[left,right],我理解的是一种搜索区间,必须把所有下标都包括。
right=nums.length-1
循环进入条件:left<=right
right=mid-1
循环结束条件:left==right+1
左闭右开:[left,right)
right=nums.length-1
进入循环条件:left<right
right=mid
循环结束条件:left==right
2.遇到的问题
1.未考虑left+right会溢出的问题,可以使用mid=left+(right-left)/2
2.第一次做另left=mid++,此时的left是没有等于加1后的left,left还是原来的mid
3.实现代码
public static int search(int[] nums, int target) { //左闭右闭
int left=0;
int right=nums.length-1;
int mid=0;
while (left<=right){
mid=(left+right)/2;
if (target>nums[mid]){
left=mid+1;
} else if (target<nums[mid]) {
right=mid-1;
}else {
return mid;
}
}
return -1;
}
public static int search2(int[] nums,int target){ //左闭右开
int left=0;
int right=nums.length;
while (left<right){
int mid=(left+right)/2;
if (nums[mid]==target){
return mid;
} else if (nums[mid]<target) {
left=mid+1;
} else if (nums[mid]>target) {
right=mid;
}
}
return -1;
}
4.题目总结
二分查找中查找某一个数,处理好搜索区间即可快速解决该问题。
27.移除元素
1.解题思路
由于需要原地改变nums的元素,所以创建另外的数组就比较麻烦。
删除数组中的某个元素,不能真正的删除,只能从后往前覆盖,最后那个是什么无所谓,新的数组内存大小和原来的一样,只是有些语言对其进行了包装,计数器减了。
暴力解法
采用双循环,如果遇到等于val的就把后面的往前移一步将val覆盖。时间复杂度O(n)
双指针解法
时间复杂度O(n),快指针用来获取新数组元素,及不需要的就不传给慢指针,慢指针用来获取新数组中需要更新的位置。
2.遇到的问题
1.暴力解法时内层循环中遇到不需要的元素i--,size同样也要--。
3.实现代码
暴力解法
class Solution {
public static int removeElement(int[] nums, int val)
{
if (nums.length == 0) {
return 0;
}
int size = nums.length;
for (int i = 0; i < size; i++)
{
if (nums[i] == val)
{
for (int j = i + 1; j < size; j++)
{
nums[j - 1] = nums[j];// 数组整体左移
}
i--;// 由于整体左移,当前下标 i 也要左移,检查新的i下标元素
size--;// 数组长度改变,外层size就不会越界检查不知道的元素
}
}
return size;
}
}
双指针解法
class Solution {
public int removeElement(int[] nums, int val) {
int slow=0;
for (int i = 0; i < nums.length; i++) {
if (nums[i]!=val){
nums[slow]=nums[i];
slow++;//在下一个位置搜集新元素
}
}
return slow;
}
}
4.题目总结
在处理数组和链表相关问题时,双指针技巧是经常用到的,双指针技巧主要分为两类:
左右指针和快慢指针。
本题使用到了快慢指针。
977.有序数组的平方
1.解题思路
1.利用 Arrays.sort(nums) (先平方再排序)
先将数组中每个元素平方,注意平方是怎么平的,我是直接两个数相乘,再利用 Arrays.sort(nums) 升序排列数组。
2.双指针(题目本身是排了序,但是有负数)
一个指左边,一个指右边
2.遇到的问题
1.^是异或运算符,是一种位符。相同为0,不同为1。我的错误是误以为是平方了。
2.双指针时,注意不能int[] nums2 = nums,因为引用一样,改一个相当于改完了,应重新new一个。
3.实现代码
1.利用 Arrays.sort(nums)
public class Pf {
public int[] sortedSquares(int[] nums) {
int slow=0;
for (int i = 0; i < nums.length; i++) {
nums[i]=nums[i]*nums[i];
}
Arrays.sort(nums);//是给nums排序,不用其他数组接收
return nums;
}
}
2.双指针
int k = nums.length - 1;//新数组中获取元素的下标
//int[] nums2 = nums;//这地方nums2与num指向同一个引用,nums改nums2也要改,nums2改nums也要改
int[] nums2=new int[k+1];
int left = 0;
int right = nums.length - 1;
while (left <= right) {
if (nums[left] * nums[left] < nums[right] * nums[right]) {
nums2[k--] = nums[right] * nums[right];
right--;
} else {
nums2[k--] = nums[left] * nums[left];
left++;
}
}
return nums2;
4.题目总结
注意引用变量,相等就等于引用了同一个地址。