数组理论基础
1. 数组是存放在连续内存空间上的相同类型数据的集合,内存地址
2. 数组下标是从0开始的,删除增加的时候需要移动其他元素的地址,
(1) 删除元素:并不是直接删除,而是将后面的元素往前移动并且覆盖。例如数组{1,2,3,4,5},删除3之后是{1,2,4,5,5},特定的语言可能会进行封装操作
3. 在Java中,二维数组访问每行的第一个元素,可以用arr[0],arr[1]。地址不是连续的
题目一:二分查找
1. 前提:有序数组,没有重复元素
2. 重点是区间的定义,也就是不变量。有两种区间方法:左闭右闭,左闭右开
题目二:移除元素
1. 题目描述:给一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度
2. 解法
(1) 暴力解法:可以实现,用两个for循环,外层for是找到值等于val的元素,内层for是将后面的元素往前覆盖
(2) 双指针:设置快慢指针,快指针遍历整个数组,慢指针用来更新新数组。
题目三:有序数组的平方
1. 题目描述:给一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,按 非递减顺序 排序
2. 用双指针从两头
题目四:长度最小子数组
1. 设置快慢指针实现滑动窗口,遍历快指针
2.要注意的点
(1) ans要设置为最大值ans=Integer.MAX_VALUE,如果ans=0,ans=Math.min(length,ans)=0,所以ans不会更新
(2) 如果选择if(sum>=target),慢指针向右一次就会跳出,因此选择while可以将慢指针右移多次
(3) while中因为刚好是符合长度的子数组,所以先输出子数组长度,更新ans。再尝试右移慢指针
题目五: 螺旋矩阵
1. 题目:给一个正整数 n
,生成一个包含 1
到 n^2
所有元素,且元素按顺时针顺序螺旋排列的 n x n
正方形矩阵 matrix
2. 注意的点
(1) while里面是判断,本题是进行n/2次循环,到最内层
(2) 设置每一次循环的起始点为(startx, starty),每次循环完之后(start+1, starty+1)
题目六:最多水的容器
1. 题目:. - 力扣(LeetCode) : 每次移动高度较小的那一个指针
public int maxArea(int[] height) {
int left=0,right=height.length-1;
int ans=0,s=0;
while (left<right){
s=Math.min(height[left],height[right])*(right-left);
ans=Math.max(s,ans);
if (height[left]<height[right])left++;
else right--;
}
return ans;
}
题目七:轮转数组
1. 题目:. - 力扣(LeetCode)
2. 思路:先都轮转,再轮转(0,k-1)和(k,nums.length-1)
public void rotate(int[] nums, int k) {
k%=nums.length;
reverse(nums,0,nums.length-1);
reverse(nums,0,k-1);
reverse(nums,k,nums.length-1);
}
public void reverse(int[] nums,int left,int right){
while (left<right){
int temp=nums[left];
nums[left]=nums[right];
nums[right]=temp;
left++;
right--;
}
}
题目八:除自身以外数组的乘积
1.题目:. - 力扣(LeetCode)
public int[] productExceptSelf(int[] nums) {
int[] ans=new int[nums.length];
ans[0]=1;
for (int i=1;i<nums.length;i++){//除自身以外左边数的乘积
ans[i]=ans[i-1]*nums[i-1];
}
int right=1;
for (int i=nums.length-1;i>=0;i--){
ans[i]*=right;
right*=nums[i];//right包含右边所有的乘积
}
return ans;
}
题目九:矩阵置零
1. 题目:73. 矩阵置零 - 力扣(LeetCode)
2. 思路:先遍历一遍数组,标记一下为0的,然后再更新
public void setZeroes(int[][] matrix) {
boolean[] row=new boolean[matrix.length];
boolean[] col=new boolean[matrix[0].length];
for (int i=0;i<matrix.length;i++){
for (int j=0;j<matrix[0].length;j++){
if (matrix[i][j]==0){
row[i]=true;
col[j]=true;
}
}
}
for (int i=0;i<matrix.length;i++){
for (int j=0;j<matrix[0].length;j++){
if (row[i] || col[j]){
matrix[i][j]=0;
}
}
}
}
题目十:旋转图像
1. 题目:48. 旋转图像 - 力扣(LeetCode)
2. 思路:先水平翻转,再主对角线翻转
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
// 水平翻转
for (int i = 0; i < n / 2; ++i) {
for (int j = 0; j < n; ++j) {
int temp = matrix[i][j];
matrix[i][j] = matrix[n - i - 1][j];
matrix[n - i - 1][j] = temp;
}
}
// 主对角线翻转
for (int i = 0; i < n; ++i) {
for (int j = 0; j < i; ++j) {
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
}
}
题目十一:搜索二维矩阵
1. 题目:240. 搜索二维矩阵 II - 力扣(LeetCode)
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
int m = matrix.length, n = matrix[0].length;
int x = 0, y = n - 1;
while (x < m && y >= 0) {
if (matrix[x][y] == target) {
return true;
}
if (matrix[x][y] > target) {
--y;
} else {
++x;
}
}
return false;
}
}