【Code Random Record】Array Brush Questions

Array method summary:

  • Dichotomy : the premise is that the array must be ordered
  • Double pointer method : complete the work of two for loops under one for loop through a fast pointer and a slow pointer
  • Sliding window : constantly adjust the starting position of the subsequence according to the current subsequence and size
  • Simulation behavior : such as a spiral matrix, write code according to the requirements of the topic

ArraysCommon APIs for tool classes in Java :

int[] arr = new int[] {
    
     1, 2, 3, 4 };

// 数组打印 (调试时方便)
Arrays.toString(arr); // [1, 2, 3, 4]

// 数组排序
Arrays.toString(arr); 

// 二分搜索 (数组必须有序)
Arrays.binarySearch(arr, 2); 

// 数组复制 (左闭右开)
int[] newArr = Arrays.copyOfRange(arr, 0, arr.length);

// 比较两个数组
Arrays.equals(arr, newArr);

// 数组全部元素赋值
Arrays.fill(arr, -1);

// 快速生成 List
List<Integer> list1 = Arrays.asList(1, 2, 3);
List<Integer> list2 = List.of(1, 2, 3);

two points

binary search*

Subject: 704. Binary Search

Given nan ordered (ascending) integer array of elements numsand a target value target, write a function to search numsfor target, and return the subscript if the target value exists, otherwise return -1.

输入: nums = [-1,0,3,5,9,12], target = 9
输出: 4
解释: 9 出现在 nums 中并且下标为 4

The premise of using dichotomy: the array is ordered.

Java source code dichotomy: suitable for finding a single value

public int search(int[] nums, int target) {
    
    
	int l = 0, r = nums.length - 1;
	while (l <= r) {
    
    
		int mid = (l + r) >> 1;
		if (nums[mid] < target) l = mid + 1;
		else if (nums[mid] > target) r = mid - 1;
		else return mid;
	}
	return - 1;
}

y total template 1: can be used to find the left boundary

public int search(int[] nums, int target) {
    
    
	int l = 0, r = nums.length - 1;
	while (l < r) {
    
    
		int mid = (l + r) >> 1;
		if (nums[mid] >= target) r = mid;
		else l = mid + 1;
	}
	if (nums[l] == target) return l;
	return - 1;
}

y total template 2: can be used to find the right boundary

public int search(int[] nums, int target) {
    
    
	int l = 0, r = nums.length - 1;
	while (l < r) {
    
    
		int mid = (l + r + 1) >> 1;
		if (nums[mid] <= target) l = mid;
		else r = mid - 1; 
	}
	if (nums[l] == target) return l;
	return -1;
}

search caret position

Topic: 35. Search insertion position

Given a sorted array and a target value, find the target value in the array and return its index. If the target value does not exist in the array, returns the position where it will be inserted in order.
Please use an algorithm with a time complexity O(logn)of .

输入: nums = [1,3,5,6], target = 5
输出: 2

The Java source code is divided into two parts:

public int searchInsert(int[] nums, int target) {
    
    
    int l = 0, r = nums.length - 1;
    while (l <= r) {
    
    
        int mid = (l + r) >> 1;
        if (nums[mid] > target) r = mid - 1;
        else if (nums[mid] < target) l = mid + 1; 
        else return mid;
    }
    return l;
}

y total template:

public int searchInsert(int[] nums, int target) {
    
    
	int l = 0, r = nums.length - 1;
	while (l < r) {
    
    
		int mid = (l + r) >> 1;
		if (nums[mid] >= target) r = mid;
		else l = mid + 1;
	}
	if (nums[l] < target) return l + 1;
	return l;
}

Find the first and last position of an element in a sorted array*

Topic: 34. Find the first and last position of an element in a sorted array - LeetCode

You are given an array of integers in non-decreasing order nums, and a target value target. Please find out where the given target value starts and ends in the array. Returns
if the target value does not exist in the array . You must design and implement an algorithm of to solve this problem.target[-1, -1]
O(log n)

输入:nums = [5,7,7,8,8,10], target = 8
输出:[3,4]

Find the left boundary by two points + find the right boundary by two points:

public int[] searchRange(int[] nums, int target) {
    
    
	if (nums.length == 0) return new int[] {
    
     -1, -1 };
	// 二分找左边界 - y总模板1
	int l = 0, r = nums.length - 1;
	while (l < r) {
    
    
		int mid = (l + r) >> 1;
		if (nums[mid] >= target) r = mid;
		else l = mid + 1;
	}
	if (nums[l] != target) return new int[] {
    
     -1, -1 };
	int lb = l;
	// 二分找右边界 - y总模板2
	l = 0; r = nums.length - 1;
	while (l < r) {
    
    
		int mid = (l + r + 1) >> 1;
		if (nums[mid] <= target) l = mid;
		else r = mid - 1;
	}
	int rb = l;
	return new int[] {
    
     lb, rb };
}

Other ideas: Divide to find a value that satisfies the condition, and spread the search boundary to the left and right (the worst possible O(n))

square root of x

Title: 69. Square root of x - LeetCode

Given a non-negative integer x, compute and xreturn the arithmetic square root of .

输入:x = 4
输出:2

Floating-point dichotomy: can output numbers after the decimal point (the situation is not as complicated as integer dichotomy, and it is easy to write)

public int mySqrt(int x) {
    
    
	double l = 1, r = x;
	while (r - l > 1e-6) {
    
     // 设置一个精度
		double mid = (l + r) / 2;
		if (mid * mid <= x) l = mid;
		else r = mid;
	}
	return (int) r;
}

Integer bisection: use x / midanti- overflow

public int mySqrt(int x) {
    
    
	int l = 1, r = x;
	while (l <= r) {
    
    
		int mid = l + (r - l) / 2;
		if (mid < x / mid) l = mid + 1;
		else if (mid > x / mid) r = mid - 1;
		else return mid;
	}
	return r;
}

effective perfect square

Title: 367. Efficient Perfect Squares - LeetCode

Given a positive num integer , write a function that returns if numis a perfect square, trueotherwise false.

输入:num = 16
输出:true

The Java source code is divided into two parts:

class Solution {
    
    
    public boolean isPerfectSquare(int num) {
    
    
        int l = 1, r = num;
        while (l <= r) {
    
    
            int mid = (l + r) >> 1;
            if (num / mid < mid) r = mid - 1;
            else if (num / mid > mid) l = mid + 1;
            else return num % mid == 0;
        }
        return false;
    }
}

y total two points:

class Solution1 {
    
    
    public boolean isPerfectSquare(int num) {
    
    
        int l = 1, r = num;
        while (l < r) {
    
    
            int mid = (l + r) >> 1;
            if (num / mid <= mid) r = mid;
            else l = mid + 1;
        }
        return (num / l == l) && (num % l == 0);
    }
}

double pointer

The double-pointer chapter contains all the questions here, refer to: [Code Random Record] Double-pointer method for brushing questions

remove element

Title: 27. Removing elements

Remove duplicates in sorted array

Topic: 26. Remove duplicates in an ordered array - LeetCode

Fast and slow pointers can be used to delete duplicate items.

moving zero

Title: 283. Moving Zero - LeetCode

compare strings with backspaces

Title: 844. Comparing Strings with Backspaces - LeetCode

Square of sorted array

Topic: Squaring an ordered array

sliding window

The smallest subarray

Title: 209. Minimum Length Subarray

Given nan array of positive integers and a positive integer target . Find the contiguous subarray
with the smallest length satisfying ≥ targetits , and return its length. If there is no subarray that meets the condition, return it . [numsl, numsl+1, ..., numsr-1, numsr]0

输入:target = 7, nums = [2,3,1,2,4,3]
输出:2
解释:子数组 [4,3] 是该条件下的长度最小的子数组。

Sliding window (two pointer):

public int minSubArrayLen(int target, int[] nums) {
    
    
	int res = Integer.MAX_VALUE, sum = 0;
	for (int l = 0, r = 0; r < nums.length; r++) {
    
    
		sum += nums[r];
		while (sum >= target) {
    
     // 收缩左窗口
			res = Math.min(res, r - l + 1);
			sum -= nums[l++];
		}
	}
	return res % Integer.MAX_VALUE;
}

fruit basket

Topic: 904. Fruit Basket - LeetCode

You are visiting a farm with a row of fruit trees planted from left to right. These trees are fruitsrepresented , where is the type offruits[i] fruit on the th itree . You want to collect as many fruits as possible. However, the owner of the farm has set some strict rules that you must follow to pick the fruit:

  • You only have two baskets, and each basket can only hold a single type of fruit. There is no limit to the total amount of fruit each basket can hold.
  • You can choose any tree to start picking, and you must pick exactly one fruit from each tree (including the tree where you started picking) . Fruit picked should match the type of fruit in the basket. Each time you pick, you will move right to the next tree and continue picking.
  • Once you get to a tree and the fruit doesn't fit the type of fruit in your basket, then you have to stop picking.
    Given an array of integers fruits, return the maximum .
输入:fruits = [1,2,1]
输出:3
解释:可以采摘全部 3 棵树。

输入:fruits = [0,1,2,2]
输出:3
解释:可以采摘 [1,2,2] 这三棵树。
如果从第一棵树开始采摘,则只能采摘 [0,1] 这两棵树。

HashMap+ Sliding window:

public int totalFruit(int[] fruits) {
    
    
	int res = 0;
	Map<Integer, Integer> map = new HashMap<>(2);
	for (int l = 0, r = 0; r < fruits.length; r++) {
    
    
		map.put(fruits[r], map.getOrDefault(fruits[r], 0) + 1);
		// 滑动窗口内水果种类 > 2 时
		while (map.size() > 2) {
    
    
			map.put(fruits[l], map.get(fruits[l]) - 1);
			if (map.get(fruits[l]) == 0) map.remove(fruits[l]);
			l++;
		}
		res = Math.max(res, r - l + 1);
	}
	return res;
}

Use array optimization HashMap:

public int totalFruit(int[] fruits) {
    
    
	int[] map = new int[fruits.length];
	int res = 0, size = 0; // 当前水果种类
	for (int l = 0, r = 0; r < fruits.length; r++) {
    
    
		if (map[fruits[r]] == 0) size++;
		map[fruits[r]]++;
		// 滑动窗口内水果种类 > 2 时
		while (size > 2) {
    
    
			map[fruits[l]]--;
			if (map[fruits[l]] == 0) size--;
			l++;
		}
		res = Math.max(res, r - l + 1);
	}
	return res;
}

minimum covering substring

Title: 76. Minimum Covering Substring - LeetCode

You are given a string s, a string t. sReturns tthe smallest substring covering all characters in . sReturns an empty string if no tsubstring covering all characters exists in "".
Note :

  • For repeated characters tin , the number of characters in the substring we are looking for must be no less than tthe number of characters in .
  • If such a substring exists sin , we guarantee that it is the only answer.

Sliding window + double pointer:

public String minWindow(String s, String t) {
    
    
	int[] map = new int[128]; // 记录字符出现次数
	for (char c : t.toCharArray()) map[c]--; // map[c]==-1 表示需要 1 个字符 c
	int count = 0; // 总共需要的字符数, count==t.length() 则满足最小覆盖子串
	// 记录最小覆盖串开始的 index 和 size
	int start = 0, size = Integer.MAX_VALUE;
	for (int l = 0, r = 0; r < s.length(); r++) {
    
    
		if (map[s.charAt(r)] < 0) count++; // 需要当前访问的字符
		map[s.charAt(r)]++; // 访问当前字符
		// 收缩窗口: map[c] > 0 表示不需要字符 c, 左指针可以往右移动
		while (l < r && map[s.charAt(l)] > 0) map[s.charAt(l++)]--;
		// 满足条件 并且 当前覆盖串长度更小, 则记录
		if (count == t.length() && r - l + 1 < size) {
    
    
			size = r - l + 1;
			start = l;
		}
	}
	return size == Integer.MAX_VALUE ? "" : s.substring(start, start + size);
}

simulation

Spiral Matrix II*

Title: 59. Spiral Matrix II

Given a positive integer n, generate 1a squaren2 matrix containing all elements of to spirally arranged in clockwise order .n x nmatrix

输入:n = 3
输出:
[[1,2,3],[8,9,4],[7,6,5]]

Simulation: bottom right, top left, four directions in order

  • Before leaving: judge whether it crosses the boundary and whether it has been visited.
  • Finished: Mark the current location as visited.
  • The first position needs to be walked manually.
public int[][] generateMatrix(int n) {
    
    
    int[][] res = new int[n][n];
    int i = 0, j = 0, cur = 2;
    res[0][0] = 1; // 手动走第一个位置
    while (cur <= n * n) {
    
    
        while (j < n - 1 && res[i][j + 1] == 0) res[i][++j] = cur++; // 右
        while (i < n - 1 && res[i + 1][j] == 0) res[++i][j] = cur++; // 下
        while (j > 0 && res[i][j - 1] == 0) res[i][--j] = cur++; // 左
        while (i > 0 && res[i - 1][j] == 0) res[--i][j] = cur++; // 上
    }
    return res;
}

spiral matrix

Title: 54. Spiral Matrix - LeetCode

Given ma nmatrix of rows and columns matrix, please return all elements in the matrix in a clockwise spiral order.

输入:matrix = 
[[1, 2,  3,  4],
 [5, 6,  7,  8],
 [9, 10, 11, 12]]

输出:[1,2,3,4,8,12,11,10,9,5,6,7]
public List<Integer> spiralOrder(int[][] matrix) {
    
    
	final int INF = 0x3f3f3f3f; // 无穷大标记为已访问
	List<Integer> res = new ArrayList<>();
	res.add(matrix[0][0]); // 第一个元素手动处理
	matrix[0][0] = INF; 
	int m = matrix.length, n = matrix[0].length;
	int k = m * n;
	int x = 0, y = 0;
	while (k-- > 1) {
    
    
		while (y < n - 1 && matrix[x][y + 1] != INF) {
    
     // 右
			res.add(matrix[x][++y]);
			matrix[x][y] = INF;
		}
		while (x < m - 1 && matrix[x + 1][y] != INF) {
    
     // 下
			res.add(matrix[++x][y]);
			matrix[x][y] = INF;
		}
		while (y > 0 && matrix[x][y - 1] != INF) {
    
     // 左
			res.add(matrix[x][--y]);
			matrix[x][y] = INF;
		}
		while (x > 0 && matrix[x - 1][y] != INF) {
    
     // 上
			res.add(matrix[--x][y]);
			matrix[x][y] = INF;
		}
	}
	return res;
}

print matrix clockwise

Topic: Sword Pointing to Offer 29. Print Matrix Clockwise - LeetCode

Enter a matrix and print each number in clockwise order from the outside to the inside.

输入:matrix = 
[[1, 2,  3,  4],
 [5, 6,  7,  8],
 [9, 10, 11, 12]]

输出:[1,2,3,4,8,12,11,10,9,5,6,7]

This question is the same as spiral matrix.

public int[] spiralOrder(int[][] matrix) {
    
    
	if (matrix.length == 0) return new int[] {
    
    };
	final int INF = 0x3f3f3f3f; // 无穷大标记为已访问
	int m = matrix.length, n = matrix[0].length;
	int[] res = new int[m * n];
	res[0] = matrix[0][0]; // 第一个元素手动处理
	matrix[0][0] = INF;
	int x = 0, y = 0, k = 1; // k 从第二个元素开始放
	while (k < m * n) {
    
    
		while (y < n - 1 && matrix[x][y + 1] != INF) {
    
    
			res[k++] = matrix[x][++y];
			matrix[x][y] = INF;
		}
		while (x < m - 1 && matrix[x + 1][y] != INF) {
    
    
			res[k++] = matrix[++x][y];
			matrix[x][y] = INF;
		}
		while (y > 0 && matrix[x][y - 1] != INF) {
    
    
			res[k++] = matrix[x][--y];
			matrix[x][y] = INF;
		}
		while (x > 0 && matrix[x - 1][y] != INF) {
    
    
			res[k++] = matrix[--x][y];
			matrix[x][y] = INF;
		}
	}
	return res;
}

Guess you like

Origin blog.csdn.net/weixin_43734095/article/details/126765764