1. 数组
数组的存储
- 数组在内存中按顺序进行存储
- Java语言中,数组按行进行存储
- 数组名代表该数组的首地址,是常量
二维数组:过n列,j个元素
数组的操作
特点: 每个元素对应一个索引(取数快);长度固定(搜索慢)
取数: 对于int数组nums,nums[0]就可以直接取到该数组的第一个元素,O(1)
增: 数组长度固定,无法超出既定长度增加元素, 最坏的情况是在最后添加元素O(n)
删: 同上,最坏的情况O(n)
改: 只能在固定index范围内进行修改,如num[0]=1, 耗费O(1)
查: 查找某个数是否存在数组中,需要从头进行遍历: O(n)
题目(待更新
704 二分查找
Tips:sorted array是进行二分查找的先验条件
class Solution {
public int search(int[] nums, int target) {
int l = 0, r = nums.length-1;
while(l<=r){
int mid = l + (r-l)/2;
if(nums[mid] == target){
return mid;
}else if(target > nums[mid]){
l = mid + 1;
}else{
r = mid - 1;
}
}
return -1;
}
}
27 移除元素
Tips:在原数组上进行修改&不考虑新长度之后的元素 means 指针1遍历数组,指针2在原数组上进行修改
class Solution {
public int removeElement(int[] nums, int val) {
int a = 0, b = 0;
while(a < nums.length){
if(nums[a]!=target){
nums[b++] = nums[a];
}
a++;
}
return b;
}
}
977 有序数组的平方
Tips:
-
负数影响平方后的排序,因此要想不被负数影响,就左右指针同时进行。
-
Ascending order输出,那么res数组就从后往前排。Arrays.sort(res)也行,就是多用了O(logn)排序,不过双指针怎样也是O(n)
class Solution {
public int[] sortedSquares(int[] nums) {
int a = 0, b = nums.length-1;
int[] res = new int[nums.length];
int idx=b;
while(a<=b){
if(nums[a]*nums[a] > nums[b]*nums[b]){
res[idx--] = nums[a]*nums[a];
a++;
}
else{
res[idx--] = nums[b]*nums[b];
b--;
}
}
return res;
}
}
209 长度最小的子数组
Tips: 左指针做index,右指针加,check
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int l = 0;
int res = nums.length+1;
while(l < nums.length){
int sum = nums[l];
if(sum >= target) return 1;
for(int r = l+1; r<nums.length; r++){
sum+=nums[r];
if(sum < target){
continue;
}else{
res = Math.min(res, r-l+1);
break;
}
}
l++;
}
return res==nums.length+1 ? 0 : res;
}
}
Tips: 或者,以右指针为主指针,不停往后加,当sum>=target时,左指针减掉。
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int l = 0, sum = 0;
int res = nums.length+1;
for(int r = 0; r < nums.length; r++){
sum += nums[r];
while(sum >= target){
res = Math.min(res, r-l+1);
sum -= nums[i++];
}
}
return res==nums.length+1 ? 0 : res;
}
}
59 螺旋矩阵
Tips: 这题挺逗的,在构建好的nxn矩阵里旋转着填数。需要上下左右四个方向分别卡着边界。四个方向标的
class Solution {
public int[][] generateMatrix(int n) {
int top = 0, down = n-1, left = 0, right = n-1;
int num = 1;
int[][] res = new int[n][n];
while(num < n*n+1){
for(int i = left; i <= right; i++){
res[top][i] = num++;
}
top++;
for(int i = top; i <= down; i++){
res[i][right] = num++;
}
right--;
for(int i = right; i >= left; i--){
res[down][i] = num++;
}
down--;
for(int i = down; i >= top; i--){
res[i][left] = num++;
}
left++;
}
return res;
}
}
48 旋转图像
Tips: 要求原地旋转矩阵,先交换ij,再根据y轴镜像旋转
1 2 3 | 1 4 7 | 7 4 1
4 5 6 | 2 5 8 | 8 5 2
7 8 9 | 3 6 9 | 9 6 3
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[j][i];
matrix[j][i] = temp;
}
}
for(int i = 0; i < n; i++){
for(int j = 0; j < n/2; j++){
int temp = matrix[i][j];
matrix[i][j] = matrix[i][n-j-1];
matrix[i][n-j-1] = temp;
}
}
}
}
56 合并区间
Tips:
- 直接开个答案int[][]或者答案List<int[]> 往里放,和最后一个做对比
- 需要根据 int[] [] 里的int[0]先排个序
class Solution {
public int[][] merge(int[][] intervals) {
// 先排序
Arrays.sort(intervals, (a,b) -> a[0]-b[0]);
List<int[]> res = new ArrayList<int[]>();
for(int i = 0; i < intervals.length; i++){
if(res.size()==0 || intervals[i][0] > res.get(res.size()-1)[1]){
res.add(intervals[i]);
}else{
res.get(res.size()-1)[1] = Math.max(res.get(res.size()-1)[1], intervals[i][1]);
}
}
return res.toArray(new int[res.size()][]);
}
}
或者,用int[] []而不是List<int[]>
class Solution {
public int[][] merge(int[][] intervals) {
// 先排序
Arrays.sort(intervals, (a,b) -> a[0]-b[0]);
int[][] res = new int[intervals.length][2];
int idx=-1;
for(int[] interval : intervals){
if(idx==-1 || interval[0] > res[idx][1]){
res[++idx] = interval;
}else{
res[idx][1] = Math.max(res[idx][1], interval[1]);
}
}
return Arrays.copyOf(res, idx+1);
}
}
0108零矩阵
Tips: 其实用flag标记row col的方式很巧妙
class Solution {
public void setZeroes(int[][] matrix) {
//Get the location of zeros
int m = matrix.length;
int n = matrix[0].length;
int[] rows = new int[m];
int[] cols = new int[n];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(matrix[i][j] == 0){
rows[i] = 1;
cols[j] = 1;
}
}
}
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
if(rows[i] == 1 || cols[j] == 1){
matrix[i][j] == 0;
}
}
}
}
}
724 寻找数组的中心下标
Tips: 这道题的思维很妙。中心索引 means 左sum = 右sum && sum*2 + nums[i] == total
class Solution {
public int pivotIndex(int[] nums) {
//首先获得nums的total sum
int total = 0;
for(int num : nums){
total += num;
}
int sum = 0;
for(int i = 0; i < nums.length; i++){
if(nums[i] + 2 * sum == total) return i;
sum += nums[i];
}
return -1;
}
}