LeetCode 热题 Hot 100
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
List<List<Integer>> res = new LinkedList<>();
/**
* BFS
*/
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
// while 循环控制从上向下一层层遍历
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> level = new LinkedList<>();
// for 循环控制每一层从左向右遍历
for (int i = 0; i < size; i++) {
TreeNode cur = queue.poll();
if (cur != null) {
level.add(cur.val);
if (cur.left != null) queue.offer(cur.left);
if (cur.right != null) queue.offer(cur.right);
}
}
res.add(level);
}
return res;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
/**
* 输入一个节点,返回以该节点为根的二叉树的最大深度
* 根据左右子树的最大深度推出原二叉树的最大深度
*/
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
int lMax = maxDepth(root.left);
int rMax = maxDepth(root.right);
// 根节点1 + max(lMax, rMax)
return Math.max(lMax, rMax) + 1;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
/**
* 1
* / \
* 2 3
* / / \
* 4 5 6
* \ /
* 7 8
*/
public TreeNode buildTree(int[] preorder, int[] inorder) {
if (preorder == null || inorder == null || preorder.length == 0 || inorder.length == 0) return null;
int preLen = preorder.length;
int inLen = inorder.length;
if (preLen != inLen) return null;
// 前序遍历
TreeNode root = new TreeNode(preorder[0]);
for (int i = 0; i < preLen; i++) {
// 找到了根节点
if (inorder[i] == root.val) {
// [0,i)
root.left = buildTree(Arrays.copyOfRange(preorder, 1, i + 1), Arrays.copyOfRange(inorder, 0, i));
// [i+1,n)
root.right = buildTree(Arrays.copyOfRange(preorder, i + 1, preLen), Arrays.copyOfRange(inorder, i + 1, preLen));
}
}
return root;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
/**
* 将 root 的左子树和右子树拉平。
* 将 root 的右子树接到左子树下方,然后将整个左子树作为右子树。
*/
public void flatten(TreeNode root) {
if (root == null) return;
// 先递归拉平左右子树
flatten(root.left);
flatten(root.right);
// 后序遍历位置
TreeNode left = root.left;
TreeNode right = root.right;
// 将左子树作为右子树
root.left = null;
root.right = left;
// 将原先的右子树接到当前右子树的末端
TreeNode p = root;
while (p.right != null) {
p = p.right;
}
p.right = right;
}
}
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
TreeNode last = null;
public void flatten(TreeNode root) {
if (root == null) return;
flatten(root.right);
flatten(root.left);
root.right = last;
root.left = null;
last = root;
}
}
class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0) return 0;
int max = 0, min = prices[0];
// 每一天的利润最大化 = 前一天的利润最大化或今天的价格-前几天的最小值
for (int i = 1; i < prices.length; i++) {
min = Math.min(prices[i], min);
max = Math.max(max, prices[i] - min);
}
return max;
}
}
class Solution {
public int longestConsecutive(int[] nums) {
// 放入set去重
Set<Integer> setNums = new HashSet<>();
for (int num : nums) {
setNums.add(num);
}
int longest = 0;
// 已经使用过的数字
Set<Integer> usedNums = new HashSet<>();
for (Integer setNum : setNums) {
if (usedNums.contains(setNum)) {
continue;
}
// 下一个数字
int nextNum = setNum + 1;
int currLongest = 1;
while (setNums.contains(nextNum)) {
currLongest++;
nextNum++;
usedNums.add(nextNum);
}
longest = Math.max(currLongest, longest);
}
return longest;
}
}
class Solution {
/**
* 一个数和它本身做异或运算结果为 0,即 a ^ a = 0;一个数和 0 做异或运算的结果为它本身,即 a ^ 0 = a。
* 对于这道题目,我们只要把所有数字进行异或,成对儿的数字就会变成 0,落单的数字和 0 做异或还是它本身,所以最后异或的结果就是只出现一次的元素。
*/
public int singleNumber(int[] nums) {
int ret = 0;
for (int i = 0; i < nums.length; i++) {
ret ^= nums[i];
}
return ret;
}
}
class Solution {
/**
* 备忘录,避免重复递归
*/
Map<String, Boolean> map = new HashMap<>();
public boolean wordBreak(String s, List<String> wordDict) {
return isContain(s, wordDict);
}
private boolean isContain(String s, List<String> wordDict) {
if ("".equals(s)) {
return true;
}
if (map.containsKey(s)) {
return false;
}
boolean res = false;
for (int i = 0; i < s.length(); i++) {
// 截取
String sub = s.substring(0, i + 1);
if (wordDict.contains(sub)) {
// 剩余子串
String lastSub = s.substring(i + 1);
// 最后返回了true就代表找到了
res = res || wordBreak(lastSub, wordDict);
if (!res) {
map.put(lastSub, true);
}
}
}
return res;
}
}
/**
* Definition for singly-linked list.
* class ListNode {
* int val;
* ListNode next;
* ListNode(int x) {
* val = x;
* next = null;
* }
* }
*/
public class Solution {
/**
* 快慢指针
*/
public boolean hasCycle(ListNode head) {
if (head == null) return false;
// 快慢指针初始化指向 head
ListNode fast = head, slow = head;
while (fast != null && fast.next != null) {
// 慢指针走一步,快指针走两步
slow = slow.next;
// 快慢指针相遇,说明含有环
fast = fast.next.next;
if (slow == fast) {
return true;
}
}
// 不包含环
return false;
}
}