目录
一,二分查找
class Solution {
public int search(int[] nums, int target) {
if(target < nums[0] || target > nums[nums.length - 1]){
return -1;
}
//左闭右开
int left = 0;
int right = nums.length;
while(left < right){
int mid = left + ((right - left) >> 1);
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
right = mid;
}else{
left = mid + 1;
}
}
return -1;
}
}
class Solution {
public int search(int[] nums, int target) {
if(target < nums[0] || target > nums[nums.length - 1]){
return -1;
}
//左闭右闭
int left = 0;
int right = nums.length - 1;
while(left <= right){
int mid = left + ((right - left) >> 1);
if(nums[mid] == target){
return mid;
}else if(nums[mid] > target){
right = mid - 1;
}else{
left = mid + 1;
}
}
return -1;
}
}
二,移除元素(原地移除)
class Solution {
public int removeElement(int[] nums, int val) {
int leftIndex = 0;
int rightIndex = nums.length - 1;
/*
1.不断的查找左边和val一样的元素,左右交换
2.如果右边交换的数和val相等,那么本次的交换肯定是无效的,
3.但是left并没有移动,right始终在移动,还会对此时left下标的元素进行判断
4.如果一样,再次无脑和右边交换,所以,无论如何会找到一个和val不等的元素
5.如果不一样,那么就对left++,进行下一个元素的判断
*/
while(leftIndex <= rightIndex){
//此时left处的元素和val相等,那么就无脑和right处的元素交换,让right--
if(nums[leftIndex] == val){
nums[leftIndex] = nums[rightIndex];
rightIndex--;
}else{
//不管left处的元素是经过1次交换得来,还是n次,还是没有,只要不等于val就++
leftIndex++;
}
}
return leftIndex;
}
}
三,有序数组的平方
class Solution {
public int[] sortedSquares(int[] nums) {
//给一个新的数组,用来保存平方和
int[] temp = new int[nums.length];
//从数组最后一个有效数组下标开始(需要升序)
int index = nums.length - 1;
//使用双指针--->一前一后,判断大小,取其大
int begin = 0;
int end = nums.length - 1;
//外部循环,当前后指针相遇的时候直接跳出循环即可
while(begin <= end){
//前后指针相遇,跳出循环
if(begin == end){
//相遇处的数的平方还未计算直接加入数组当中
temp[index] = nums[begin] * nums[begin];
break;
}else if(nums[begin] * nums[begin] > nums[end] * nums[end]){
temp[index] = nums[begin] * nums[begin];
begin++;
}else{
temp[index] = nums[end] * nums[end];
end--;
}
index--;
}
return temp;
}
}
四,长度最小的子数组(滑动窗口)
class Solution {
public int minSubArrayLen(int target, int[] nums) {
//通过滑动窗口来解决
//start为滑动窗口的开始位置
int start = 0;
//滑动窗口内的和
int sum = 0;
//滑动窗口的大小
int result = Integer.MAX_VALUE;
//end为滑动窗口的结束位置
for(int end = 0;end < nums.length;end++){
//假如滑动窗口内的值不满足要求(在本题中,就是>= target)就一直相加
sum += nums[end];
//当滑动窗口内的值满足条件后
while(sum >= target){
//先比较此时滑动窗口的大小是不是最小的,是的话就替换
result = Math.min(result,end - start + 1);
//因为不知道最后相加的这个元素减掉开始位置的元素是否还是满足条件的
//努力让滑动窗口的足够小,能小则小
sum -= nums[start];
start++;
}
//如果在此处,说明,已经不满足条件了
//如果end即结束位置还没到数组的最后一个元素就继续相加
}
//这时已经说明滑动窗口是最小的了(有元素的情况)
//但是,万一数组为空,或者是数组本身所有元素加在一起都没有target大
//那么就需要设置为0了,即需要判断一下是不是第二种的情况
return result == Integer.MAX_VALUE ? 0 : result;
}
}
五,螺旋矩阵
class Solution {
public int[][] generateMatrix(int n) {
//创建一个新的二维数组(n * n)
int[][] matrix = new int[n][n];
//定义左,右,上,下边界(取下闭右闭)
int left = 0,right = n - 1,top = 0,bottom = n - 1;
//定义需要填入的数字num,并且设定循环的边界为target,即数组需要填入的最大的元素
int num = 1,target = n*n;
//设定循环条件
while(num <= target){
//往matrix[0][i]排插入元素
for(int i = left; i <= right;i++){
//知道谁变谁不变,在这里,行不变,列变
matrix[top][i] = num;
num++;
}
top++;
//往matrix[i][right]里面插入元素
for(int i = top;i <= bottom;i++){
//在这里,行变,列不变
matrix[i][right] = num;
num++;
}
right--;
for(int i = right;i >= left;i--){
matrix[bottom][i] = num;
num++;
}
bottom--;
for(int i = bottom;i >= top;i--){
matrix[i][left] = num;
num++;
}
left++;
}
return matrix;
}
}
六,总结
- 数组的解题思路,主要从循环遍历(可使用二分),双指针法,滑动窗口,模拟行为入手
- 数组最难的点在于边界的判定