数组简介
方法1:前缀和
class Solution {
public int findMiddleIndex(int[] nums) {
int tol = 0, s = 0;
for(int num : nums)
tol += num;
for(int i = 0; i < nums.length; i++) {
if(s == tol - s - nums[i])
return i;
s += nums[i];
}
return -1;
}
}
方法1:二分查找
class Solution {
public int searchInsert(int[] nums, int target) {
int left = 0, right = nums.length;
while(left < right) {
int mid = (left + right) >> 1;
if(nums[mid] < target)
left = mid + 1;
else
right = mid;
}
return left;
}
}
方法1:贪心
- 排序 (a, b) -> a[0] - b[0]
- 列表转数组 toArray(new int[M][N])
class Solution {
public int[][] merge(int[][] intervals) {
Arrays.sort(intervals, (a, b) -> a[0] - b[0]);
List<int []> ans = new ArrayList<int []>();
for(int[] info : intervals) {
int n = ans.size(), left = info[0], right = info[1];
if(n == 0 || ans.get(n - 1)[1] < left)
ans.add(info);
else
ans.get(n - 1)[1] = Math.max(ans.get(n - 1)[1], right);
}
return ans.toArray(new int[ans.size()][2]);
}
}
class Solution:
def merge(self, intervals: List[List[int]]) -> List[List[int]]:
intervals.sort(key=lambda x: x[0])
ans = list()
for (left, right) in intervals:
if not ans or ans[-1][1] < left:
ans.append([left, right])
else:
ans[-1][1] = max(ans[-1][1], right)
return ans
二维数组简介
方法1:辅助数组
class Solution {
public void rotate(int[][] matrix) {
int n = matrix.length;
int[][] temp = new int[n][n];
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++)
temp[i][j] = matrix[n - 1 - j][i];
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++)
matrix[i][j] = temp[i][j];
}
}
}
方法1:标记数组
class Solution {
public void setZeroes(int[][] matrix) {
int n = matrix.length, m = matrix[0].length;
boolean[] row = new boolean[n];
boolean[] col = new boolean[m];
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(matrix[i][j] == 0) {
row[i] = true; col[j] = true;
}
}
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < m; j++) {
if(row[i] || col[j])
matrix[i][j] = 0;
}
}
}
}
方法1:模拟
class Solution {
public int[] findDiagonalOrder(int[][] mat) {
int m = mat.length, n = mat[0].length, k = 0;
int[] ans = new int[m * n];
for(int i = 0; i < m + n - 1; i++) {
if(i % 2 == 0) {
int x = Math.min(i, m - 1);
int y = Math.max(0, i - m + 1);
while(x >= 0 && y < n)
ans[k++] = mat[x--][y++];
} else {
int x = Math.max(0, i - n + 1);
int y = Math.min(i, n - 1);
while(x < m && y >= 0)
ans[k++] = mat[x++][y--];
}
}
return ans;
}
}
字符串简介
方法1:横向扫描
class Solution {
public String longestCommonPrefix(String[] strs) {
String prefix = strs[0];
for(int i = 1; i < strs.length; i++) {
prefix = commonPrefix(prefix, strs[i]);
if(prefix == "") return prefix;
}
return prefix;
}
static String commonPrefix(String str1, String str2) {
int length = Math.min(str1.length(), str2.length());
for(int i = 0; i < length; i++) {
if(str1.charAt(i) != str2.charAt(i))
return str1.substring(0, i);
}
return str1.substring(0, length);
}
}
方法2:纵向扫描
class Solution {
public String longestCommonPrefix(String[] strs) {
int length = strs[0].length(), count = strs.length;
for(int i = 0; i < length; i++) {
char c = strs[0].charAt(i);
for(int j = 1; j < count; j++) {
if(i == strs[j].length() || c != strs[j].charAt(i))
return strs[0].substring(0, i);
}
}
return strs[0];
}
}
方法1:动态规划
class Solution {
public String longestPalindrome(String s) {
int maxLen = 1, begin = 0, n = s.length();
boolean[][] dp = new boolean[n][n];
for(int i = 0; i < n; i++)
dp[i][i] = true;
for(int L = 2; L <= n; L++) {
for(int i = 0; i < n; i++) {
int j = i + L - 1;
if(j >= n) break;
if(s.charAt(i) == s.charAt(j)) {
if(i + 1 == j)
dp[i][j] = true;
else
dp[i][j] = dp[i + 1][j - 1];
} else {
dp[i][j] = false;
}
if(dp[i][j] && j - i + 1 > maxLen) {
maxLen = j - i + 1; begin = i;
}
}
}
return s.substring(begin, begin + maxLen);
}
}
方法1:自带函数
class Solution {
public String reverseWords(String s) {
s = s.trim();
List<String> wordList = Arrays.asList(s.split("\\s+"));
Collections.reverse(wordList);
return String.join(" ", wordList);
}
}
class Solution:
def reverseWords(self, s: str) -> str:
return " ".join(reversed(s.split()))
双指针技巧
方法1:双指针
class Solution {
public void reverseString(char[] s) {
for(int i = 0, j = s.length - 1; i < j; i++, j--) {
char temp = s[i]; s[i] = s[j]; s[j] = temp;
}
}
}
方法1:贪心
class Solution {
public int arrayPairSum(int[] nums) {
Arrays.sort(nums);
int ans = 0;
for(int i = 0; i < nums.length; i += 2)
ans += nums[i];
return ans;
}
}
方法1:暴力
class Solution {
public int[] twoSum(int[] nums, int target) {
int n = nums.length;
for(int i = 0; i < n - 1; i++) {
for(int j = i + 1; j < n; j++) {
if(nums[i] + nums[j] == target)
return new int[]{i, j};
}
}
return new int[0];
}
}
方法2:哈希表
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>();
for(int i = 0; i < nums.length; i++) {
if(hashtable.containsKey(target - nums[i]))
return new int[]{hashtable.get(target - nums[i]), i};
hashtable.put(nums[i], i);
}
return new int[0];
}
}
方法1:快慢指针
class Solution {
public int removeElement(int[] nums, int val) {
int n = nums.length, slow = 0;
for(int fast = 0; fast < n; fast++) {
if(nums[fast] != val)
nums[slow++] = nums[fast];
}
return slow;
}
}
方法2:左右指针
class Solution {
public int removeElement(int[] nums, int val) {
int left = 0, right = nums.length - 1;
while(left <= right) {
if(nums[left] == val)
nums[left] = nums[right--];
else
left++;
}
return left;
}
}
方法1:模拟
class Solution {
public int findMaxConsecutiveOnes(int[] nums) {
int ans = 0, cnt = 0;
for(int i = 0; i <= nums.length; i++) {
if(i == nums.length || nums[i] == 0) {
ans = Math.max(ans, cnt); cnt = 0;
} else
cnt++;
}
return ans;
}
}
方法1:滑动窗口
class Solution {
public int minSubArrayLen(int target, int[] nums) {
int n = nums.length;
int left = 0, right = 0, val = 0, ans = n + 1;
while(right < n) {
val += nums[right++];
while(val >= target) {
ans = Math.min(ans, right - left);
val -= nums[left++];
}
}
return ans == n + 1 ? 0 : ans;
}
}
小结
方法1:数学
class Solution {
public List<List<Integer>> generate(int numRows) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
for(int i = 0; i < numRows; i++) {
List<Integer> temp = new ArrayList<Integer>();
for(int j = 0; j <= i; j++) {
if(j == 0 || j == i)
temp.add(1);
else
temp.add(ans.get(i - 1).get(j - 1) + ans.get(i - 1).get(j));
}
ans.add(temp);
}
return ans;
}
}
方法1:递推
class Solution {
public List<Integer> getRow(int rowIndex) {
List<Integer> ans = new ArrayList<Integer>();
ans.add(1);
for(int i = 1; i <= rowIndex; i++) {
ans.add(0);
for(int j = i; j > 0; j--)
ans.set(j, ans.get(j - 1) + ans.get(j));
}
return ans;
}
}
方法2:线性递推
class Solution {
public List<Integer> getRow(int rowIndex) {
List<Integer> ans = new ArrayList<Integer>();
ans.add(1);
for(int i = 1; i <= rowIndex; i++) {
long res = (long)ans.get(i - 1) * (rowIndex - i + 1);
ans.add((int)(res / i));
}
return ans;
}
}
方法1:二分查找
class Solution {
public int findMin(int[] nums) {
int low = 0, high = nums.length - 1;
while(low < high) {
int mid = (low + high) >> 1;
if(nums[mid] < nums[high])
high = mid;
else
low = mid + 1;
}
return nums[low];
}
}
方法1:双指针
class Solution {
public int removeDuplicates(int[] nums) {
int slow = 1;
for(int fast = 1; fast < nums.length; fast++) {
if(nums[fast] != nums[fast - 1])
nums[slow++] = nums[fast];
}
return slow;
}
}
方法1:双指针
class Solution {
public void moveZeroes(int[] nums) {
int slow = 0;
for(int fast = 0; fast < nums.length; fast++) {
if(nums[fast] != 0) {
int temp = nums[slow];
nums[slow++] = nums[fast];
nums[fast] = temp;
}
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构