哈希
双指针
滑动窗口
子串
普通数组
矩阵
链表
二叉树
- 二叉树的中序遍历
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> reusltList = new ArrayList<>();
inorderVisited(root, reusltList);
return reusltList;
}
private void inorderVisited(TreeNode root, List<Integer> reusltList) {
if (root == null) {
return;
}
inorderVisited(root.left, reusltList);
reusltList.add(root.val);
inorderVisited(root.right, reusltList);
}
}
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> reusltList = new ArrayList<>();
inorderVisited(root, reusltList);
return reusltList;
}
private void inorderVisited(TreeNode root, List<Integer> reusltList) {
Stack<TreeNode> stack = new Stack<>();
while (root != null || !stack.empty()) {
while (root != null) {
stack.push(root);
root = root.left;
}
root = stack.pop();
reusltList.add(root.val);
root = root.right;
}
}
}
图论
回溯
二分查找
栈
堆
贪心算法
动态规划
- 爬楼梯
class Solution {
public int climbStairs(int n) {
int[] dp = new int[n+1];
dp[0] = 1;
dp[1] = 1;
for(int i = 2;i <= n; i++){
dp[i] = dp[i-1] + dp[i-2];
}
return dp[n];
}
}
- 打家劫舍
class Solution {
public int rob(int[] nums) {
if (nums.length == 0) {
return 0;
}
int len = nums.length;
int[] dp = new int[len+1];
dp[0] = 0;
dp[1] = nums[0];
for(int i = 2; i <= len; i++){
dp[i] = Math.max(dp[i-1], dp[i-2] + nums[i-1]);
}
return dp[len];
}
}
- 完全平方数
class Solution {
public int numSquares(int n) {
int[] dp = new int[n + 1];
for(int i = 1; i <= n;i++) {
int minn = Integer.MAX_VALUE;
for(int j = 1; j * j <= i; j++){
minn = Math.min(minn, dp[i - j * j]);
}
dp[i] = minn + 1;
}
return dp[n];
}
}
- 零钱兑换
class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int coin : coins) {
if (i < coin) {
continue;
}
dp[i] = Math.min(dp[i], dp[i - coin]);
}
dp[i] += 1;
}
return dp[amount] > amount ? -1 : dp[amount];
}
}
class Solution {
public int coinChange(int[] coins, int amount) {
int[] dp = new int[amount + 1];
Arrays.fill(dp, amount + 1);
dp[0] = 0;
for (int i = 1; i <= amount; i++) {
for (int coin : coins) {
if (i < coin) {
continue;
}
dp[i] = Math.min(dp[i], dp[i - coin] + 1);
}
}
return (dp[amount] == amount + 1) ? -1 : dp[amount];
}
}
- 分割等和子集
class Solution {
public boolean canPartition(int[] nums) {
if (nums == null || nums.length == 0) {
return false;
}
int len = nums.length;
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 != 0)
return false;
int target = sum / 2;
int[] dp = new int[target + 1];
for (int i = 0; i < len; i++) {
for (int j = target; j >= nums[i]; j--) {
dp[j] = Math.max(dp[j], dp[j - nums[i]] + nums[i]);
}
if (dp[target] == target) {
return true;
}
}
return dp[target] == target;
}
}
多维动态规划
技巧
- 只出现一次的数字
class Solution {
public int singleNumber(int[] nums) {
int ans = 0;
for (int num : nums) {
ans ^= num;
}
return ans;
}
}