滑动窗口
长度最小的子数组
使用滑动窗口,当前窗口大小的数组的和比目标值小就加大窗口(r++),当前窗口大小的数组的和比目标值大或相等,就减小窗口大小(l++),并更新最小数组大小。
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
int l=0,r=0;
int sum = 0;
int min = n+1;
while(r<n){
sum+=nums[r];
while(sum>=target){
min = r-l+1>min?min:r-l+1;
sum -= nums[l];
l++;
}
r++;
}
return min>n?0:min;
}
无重复字符的最长子串
使用两个指针来确定窗口大小(L,R),使用map来记录对应字符和其对应的下标,遍历的时候判断当前字符是否在map中存过了,没存过就放进map,出现过就获取他的下标index,对下标进行判断,判断规则为,index不为null且index要大于指针L,满足条件则更新max。遍历结束后不要忘了再更新一次max;
public int lengthOfLongestSubstring(String s) {
int n = s.length();
Map<Character,Integer> map = new HashMap<>();
int l=0,r=0;
int max = 0;
while (r<n){
Integer index = map.get(s.charAt(r));
if(index != null && index >= l){
if(max<r-l){
max = r-l;
}
l=index+1;
}
map.put(s.charAt(r),r);
r++;
}
if(max<r-l){
max = r-l;
}
return max<=0?n:max;
}
矩阵
有效的数独
使用3个数组来分别记录行,列,9宫格的数字出现的情况,如果遍历到某位置时,记录该位置值的数组对应位置的值已经不为0了,则说明不满足规则。
public boolean isValidSudoku(char[][] board) {
int[][] map1 = new int[9][9]; //hang
int[][] map2 = new int[9][9]; //lie
int[][][] map3 = new int[3][3][9];
for (int i = 0; i < 9; i++) {
for (int j = 0; j < 9; j++) {
if (board[i][j]=='.'){
continue;
}else {
if(map1[i][board[i][j]-'1']==0){
map1[i][board[i][j]-'1']++;
}else{
return false;
}
if(map2[board[i][j]-'1'][j]==0){
map2[board[i][j]-'1'][j]++;
}else {
return false;
}
int l = i/3;
int r = j/3;
if(map3[l][r][board[i][j]-'1']==0){
map3[l][r][board[i][j]-'1']++;
}else {
return false;
}
}
}
}
return true;
}
螺旋矩阵
确定上下左右四个边界,按照上右下左的顺序循环输出。
public List<Integer> spiralOrder(int[][] matrix) {
int lie = matrix.length;
int hang = matrix[0].length;
int count = 1;
int sum = lie*hang;
int top,bottom,left,right;
top = 0;
bottom = lie-1;
left = 0;
right = hang-1;
List<Integer> res = new ArrayList<>();
while (res.size()<sum){
for (int i = left; i <= right; i++) {
if (res.size()<sum){
res.add(matrix[top][i]);
}
}
top++;
for (int i = top; i <= bottom; i++) {
if (res.size()<sum){
res.add(matrix[i][right]);
}
}
right--;
for (int i = right; i >= left ; i--) {
if (res.size()<sum){
res.add(matrix[bottom][i]);
}
}
bottom--;
for (int i = bottom; i >= top; i--) {
if (res.size()<sum){
res.add(matrix[i][left]);
}
}
left++;
}
return res;
}
旋转图像
先对图像进行转置操作,在对图像进行水平翻转。
1 | 2 | 3 |
4 | 5 | 6 |
7 | 8 | 9 |
1 | 4 | 7 |
2 | 5 | 8 |
3 | 6 | 9 |
7 | 4 | 1 |
8 | 5 | 2 |
9 | 6 | 3 |
public void rotate(int[][] matrix) {
int n = matrix.length;
for (int i = 0; i < n; i++) {
for (int j = i + 1; 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++) {
int l=0,r=n-1;
while (l<r){
int temp = matrix[i][l];
matrix[i][l++]=matrix[i][r];
matrix[i][r--]=temp;
}
}
}
矩阵置零
建立两个数组分别记录0所在的行、列位置,然后依次为依据进行指令操作。
public void setZeroes(int[][] matrix) {
int m = matrix.length;
int n = matrix[0].length;
boolean[] rows = new boolean[m];
boolean[] cols = new boolean[n];
// 遍历矩阵,记录需要被置零的行和列
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == 0) {
rows[i] = true;
cols[j] = true;
}
}
}
// 根据记录的行列,将对应的元素置零
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (rows[i] || cols[j]) {
matrix[i][j] = 0;
}
}
}
}