0%

题型技巧总结:栈;)

8-1 常考题型1 - 平衡符号 (括号匹配)

  • 栈的实现:顺序栈、链式栈
  • Parentheses(){}[]

20.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public boolean isValid(String s) {
if (s.isEmpty())
return true;
Stack<Character> stack = new Stack<Character>();
for (char c:s.toCharArray()) {
if (c == '(')
stack.push(')');
else if (c == '{')
stack.push('}');
else if (c== '[')
stack.push(']');
else if(stack.isEmpty() || c != stack.pop())//当不为左括号时候,说明c是右括号,
//stack.pop弹出栈元素中存储的右括号元素,比较这两个右括号是否相等。
return false;
}
if (stack.isEmpty())//判断相对情况下的第一个字符是否为’),},】‘这种类型的。
//防止里面还有残余的括号
//当stack为空时输入一个c=)时,stack内没有(与之对应,则认为false
return true;
return false;
}
}

8-2 常考题型2 - 压栈匹配1(LeetCode 394题)

  • 前后顺序相关联(最近遇到的东西先处理 )
  • 有特殊字符“[]...”,或字母代表特殊意义

71.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import java.util.*;
class Solution {
public String simplifyPath(String path) {
Stack<String> stack = new Stack<>();
String[] paths = path.split("/+");
for (String s : paths) {
if (s.equals("..")) {
if(!stack.isEmpty()) {
stack.pop();
}
} else if (!s.equals(".") && !s.equals("")) {
stack.push(s);
}
}
String res = "";
while (!stack.isEmpty()) {
res = "/" + stack.pop() + res;
}
if (res.length() == 0) {
return "/";
}
return res;
}
}

8-4 常考题型3 - 表达式计算1(LeetCode 150题)

  • 正常计算a + b * c
  • 逆波兰表示法(后缀表达法)a b c * +

224.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
/*
* @lc app=leetcode.cn id=224 lang=java
*
* [224] 基本计算器
*/

// @lc code=start
class Solution {
public int calculate(String s) {
Stack<Integer> stack = new Stack<>();
int sign = 1;
int res = 0;
for (int i = 0; i < s.length(); i++) {
//判断当前是否为数字
if (Character.isDigit(s.charAt(i))) {
//转换成数字
int num = s.charAt(i) - '0';
//判断下一位是不是还是数字,case:123
while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) {
num = num * 10 + s.charAt(i + 1) - '0';
i++;
}
res += num * sign;
} else if (s.charAt(i) == '+') {
sign = 1;
} else if (s.charAt(i) == '-') {
sign = -1;
} else if (s.charAt(i) == '(') {
//1 - 2可以看成 1 + (-2)
stack.push(res);
stack.push(sign);//sign会先Pop出来
//恢复到初始化状态
res = 0;
sign = 1;
} else if (s.charAt(i) == ')') {
res = res * stack.pop() + stack.pop();
}
}
return res;
}
}
// @lc code=end

常考题型4 - 迭代极值1(LeetCode 42题)

341. Flatten Nested List Iterator(压栈匹配) (08:30)

385. Mini Parser(压栈匹配) (09:15)

105. Construct Binary Tree from Preorder and Inorder Traversal (13:14)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//inorder : 有根节点的左子树在左边,右子树在右边的性质
//inorder : 当前节点下一个的位置是它的右子树
//preorder : 当前节点下一个的位置是它的左子树
//time : O(n)
//space : O(n) 递归调用
class Solution {
public TreeNode buildTree(int[] preorder, int[] inorder) {
return helper(0, 0, inorder.length - 1, preorder, inorder);

}
public TreeNode helper(int preStart, int inStart, int inEnd, int[] preorder, int[] inorder) {//不需要preorder的end
if (preStart > preorder.length - 1 || inStart > inEnd) {
return null;
}
//preorder的第一个节点就是根节点
TreeNode root = new TreeNode(preorder[preStart]);
//表示在Inorder中root的位置在哪
int inIdex = 0;
for (int i = inStart; i <= inEnd; i++) {
if (inorder[i] == root.val) {
inIdex = i;
}
}
//prestart已经找完了,要找下一个节点,start也只能从先序遍历里面找
root.left = helper(preStart + 1, inStart, inIdex - 1, preorder, inorder);
//preStart + inorder中左子树的元素 + 1得到右子树的启始位置
root.right = helper(preStart + inIdex - inStart + 1, inIdex + 1, inEnd, preorder, inorder);
return root;
}

}

106. Construct Binary Tree from Inorder and Postorder Traversal (15:17)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
int pInorder;
int pPostorder;
public TreeNode buildTree(int[] inorder, int[] postorder) {
pInorder = inorder.length - 1;
pPostorder = postorder.length - 1;
return helper(inorder, postorder, null);
}
public TreeNode helper(int[] inorder, int[] postorder, TreeNode end) {
if (pPostorder < 0) {
return null;
}
TreeNode root = new TreeNode(postorder[pPostorder--]);
//代表有右孩子
if (inorder[pInorder] != root.val) {
root.right = helper(inorder, postorder, root);
}
pInorder--;//如果找到了
if ((end == null) || (inorder[pInorder] != end.val)) {
root.left = helper(inorder, postorder, end);
}
return root;
}
}

95. Unique Binary Search Trees II(不重要) (11:41)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public List<TreeNode> generateTrees(int n) {
if (n == 0) return new ArrayList<>();
return genTreeList(1, n);
}

public List<TreeNode> genTreeList(int start, int end) {
List<TreeNode> list = new ArrayList<>();
if (start > end) {
list.add(null);
}
for (int idx = start; idx <= end; idx++) {
List<TreeNode> leftList = genTreeList(start, idx - 1);
List<TreeNode> rightList = genTreeList(idx + 1, end);
for (TreeNode left : leftList) {
for (TreeNode right : rightList) {
TreeNode root = new TreeNode(idx);
root.left = left;
root.right = right;
list.add(root);
}
}
}
return list;
}
}

108. Convert Sorted Array to Binary Search Tree binary search(BST) (05:12)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public TreeNode sortedArrayToBST(int[] nums) {
if (nums == null || nums.length == 0) return null;
return helper(nums, 0, nums.length - 1);
}
public TreeNode helper(int[] nums, int left, int right) {
if (left > right) return null;
int mid = (right - left) / 2 + left;
TreeNode node = new TreeNode(nums[mid]);
node.left = helper(nums, left, mid - 1);
node.right = helper(nums, mid + 1, right);
return node;
}
}

109. Convert Sorted List to Binary Search Tree binary search(BST) (04:40)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//时间复杂度是O(n) 空间复杂度O(n)
class Solution {
//slow就是终点
public TreeNode sortedListToBST(ListNode head) {
if (head == null) return null;
return toBST(head, null);
}
public TreeNode toBST(ListNode head, ListNode tail) {
if (head == tail) return null;
ListNode slow = head;//中点
ListNode fast = head; //走完
while (fast != tail && fast.next != tail) {
fast = fast.next.next;
slow = slow.next;
}
TreeNode root= new TreeNode(slow.val);
root.left = toBST(head, slow);
root.right = toBST(slow.next ,tail);
return root;
}
}

Inorder

应用场景:

  • BST适用于升序的序列

230.Kth Smallest Element in a BST(BST & Inorder

Given a binary search tree, write a function kthSmallest to find the kth smallest element in it.

Example 1:

1
2
3
4
5
6
7
Input: root = [3,1,4,null,2], k = 1
3
/ \
1 4
\
2
Output: 1

Example 2:

1
2
3
4
5
6
7
8
9
Input: root = [5,3,6,2,4,null,null,1], k = 3
5
/ \
3 6
/ \
2 4
/
1
Output: 3

Follow up:
What if the BST is modified (insert/delete operations) often and you need to find the kth smallest frequently? How would you optimize the kthSmallest routine?

Constraints:

  • The number of elements of the BST is between 1 to 10^4.
  • You may assume k is always valid, 1 ≤ k ≤ BST's total elements.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/**
* 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 {
int count;
int res;
public int kthSmallest(TreeNode root, int k) {
count = k;
res = 0;
helper(root);
return res;
}
public void helper(TreeNode root){
if (root == null) return;
helper(root.left);
count--;
if (count == 0) {
res = root.val;
}
helper(root.right);
}
}

Postorder

应用场景:

  • 子模块
  • 子树
  • 从底向上

124.Binary Tree Maximum Path Sum

Given a non-empty binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.

Example 1:

1
2
3
4
5
6
7
Input: [1,2,3]

1
/ \
2 3

Output: 6

Example 2:

1
2
3
4
5
6
7
8
9
Input: [-10,9,20,null,null,15,7]

-10
/ \
9 20
/ \
15 7

Output: 42
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//找左边最大路径或者右边最大路径和拐点(根节点)的值
class Solution {
int res;//全局变量有值传递和引用传递的区别
public int maxPathSum(TreeNode root) {
if (root == null) return 0;
res = Integer.MIN_VALUE;//求最大值就是 和最小值进行比较
helper(root);
return res;
}
public int helper(TreeNode root) {
if (root == null) return 0;
int left = Math.max(0, helper(root.left));//在这里只取正数
int right = Math.max(0, helper(root.right));
res = Math.max(res, left + right + root.val);
return Math.max(left ,right) + root.val;
}
}

104.Maximum Depth of Binary Tree

Given a binary tree, find its maximum depth.

The maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.

Note: A leaf is a node with no children.

Example:

Given binary tree [3,9,20,null,null,15,7],

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

return its depth = 3.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int maxDepth(TreeNode root) {
if (root == null) return 0;
int left = maxDepth(root.left) + 1;
return Math.max(left, right);
}
}

第九天LeetCode题目(树的Inorder和Postorder);)

235. Lowest Common Ancestor of a Binary Search Tree(BST)

Given a binary search tree (BST), find the lowest common ancestor (LCA) of two given nodes in the BST.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Given binary search tree: root = [6,2,8,0,4,7,9,null,null,3,5]

img

Example 1:

1
2
3
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 8
Output: 6
Explanation: The LCA of nodes 2 and 8 is 6.

Example 2:

1
2
3
Input: root = [6,2,8,0,4,7,9,null,null,3,5], p = 2, q = 4
Output: 2
Explanation: The LCA of nodes 2 and 4 is 2, since a node can be a descendant of itself according to the LCA definition.

Note:

  • All of the nodes’ values will be unique.
  • p and q are different and both values will exist in the BST.
1
2
3
4
5
6
7
8
9
10
11
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root.val > p.val && root.val > q.val) {
return lowestCommonAncestor(root.left, p, q);
} else if (root.val < p.val && root.val < q.val) {
return lowestCommonAncestor(root.right, p, q);
} else {
return root;
}
}
}

270. Closest Binary Search Tree Value(BST)付费题

找出BST中离Target值最接近的节点

1
2
3
4
5
6
7
8
9
10
11
12
public int ClosestValue(TreeNode root, double target) {
int res = root.val;
while (root != null) {
//每次和res比较,看哪个更小,看比target大还是小,就知道走左还是右
if (Math.abs(target - root.val) < Math.abs(tartget - res)) {
res = root.val;
}
root = root.val > target ? root.left : root.right;
}
return res;
}
}

173. Binary Search Tree Iterator(BST & Inorder)

Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST.

Calling next() will return the next smallest number in the BST.

Example:

img

1
2
3
4
5
6
7
8
9
10
BSTIterator iterator = new BSTIterator(root);
iterator.next(); // return 3
iterator.next(); // return 7
iterator.hasNext(); // return true
iterator.next(); // return 9
iterator.hasNext(); // return true
iterator.next(); // return 15
iterator.hasNext(); // return true
iterator.next(); // return 20
iterator.hasNext(); // return false

Note:

  • next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.

  • You may assume that next() call will always be valid, that is, there will be at least a next smallest number in the BST when next() is called.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    //中序遍历从小到大递增
    class BSTIterator {
    private TreeNode cur;
    private Stack<TreeNode> stack;

    public BSTIterator(TreeNode root) {
    cur = root;
    stack = new Stack<>();
    }

    /** @return whether we have a next smallest number */
    public boolean hasNext() {
    if (!stack.isEmpty() || cur != null) {
    return true;
    }
    return false;
    }

    /** @return the next smallest number */
    public int next() {
    while (cur != null) {
    stack.push(cur);
    cur = cur.left;
    }
    cur = stack.pop();
    int val = cur.val;
    cur = cur.right;
    return val;
    }
    }

285. Inorder Successor in BST(BST & Inorder)

在BST中找给定节点P的下一个节点是什么

1
2
3
4
5
6
7
8
9
10
11
12
13
public TreeNode InorderSuccessor(TreeNode root, TreeNode p) {
//判断当前节点和节点P谁的值大
TreeNode res = null;
while (root != null) {
if (root.val <= p.val) {
root = root.right;
} else {
res = root;//root节点可能就是res
root = root.left;

}
return res;
}

99. Recover Binary Search Tree(BST & Inorder)

Share

Two elements of a binary search tree (BST) are swapped by mistake.

Recover the tree without changing its structure.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Input: [1,3,null,null,2]

1
/
3
\
2

Output: [3,1,null,null,2]

3
/
1
\
2

Example 2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Input: [3,1,4,null,null,2]

3
/ \
1 4
/
2

Output: [2,1,4,null,null,3]

2
/ \
1 4
/
3

Follow up:

  • A solution using O(n) space is pretty straight forward.
  • Could you devise a constant space solution?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
TreeNode first = null;
TreeNode second = null;
TreeNode prev = null;//记录前一个节点,总比前一个节点大(二叉树性质)
public void recoverTree(TreeNode root) {
if (root == null) return;
helper(root);
int temp = first.val;
first.val = second.val;
second.val = temp;
}
public void helper(TreeNode root) {
if (root == null) return;
helper(root.left);//从左边的叶节点开始执行,
if (prev != null && prev.val >= root.val) {
if (first == null) first = prev;
second = root;
}
prev = root;
helper(root.right);
}
}

124. Binary Tree Maximum Path Sum(Postorder)

Given a non-empty binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path must contain at least one node and does not need to go through the root.

Example 1:

1
2
3
4
5
6
7
Input: [1,2,3]

1
/ \
2 3

Output: 6

Example 2:

1
2
3
4
5
6
7
8
9
Input: [-10,9,20,null,null,15,7]

-10
/ \
9 20
/ \
15 7

Output: 42
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//找左边最大路径或者右边最大路径和拐点(根节点)的值
class Solution {
int res;//全局变量有值传递和引用传递的区别
public int maxPathSum(TreeNode root) {
if (root == null) return 0;
res = Integer.MIN_VALUE;//求最大值就是 和最小值进行比较
helper(root);
return res;
}
public int helper(TreeNode root) {
if (root == null) return 0;
int left = Math.max(0, helper(root.left));//在这里只取正数
int right = Math.max(0, helper(root.right));
res = Math.max(res, left + right + root.val);
return Math.max(left ,right) + root.val;
}
}

250. Count Univalue Subtrees(Postorder)付费题

有多少个Subtree有同样的val

HINT:dango::单独的叶子节点也算一个子树

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//PostOrder
//time:O(n)遍历一遍
//space:O(n)
int res;
public int countUnivalueSubtrees(TreeNode root) {
res = 0;
helper(res);
return res;
}
public boolean helper(TreeNode root) {
if (root == null) return true;
boolean left = helper(root.left);//子树为空的时候为TRUE
boolean right = helper(root.right);

if (left && right) {
if (root.left != null && root.val != root.left.val) {
return false;
}
if (root.right != null && root.val != root.right.val) {
return false;
}
res++;
return true;
}
return false;
}

236.Lowest Common Ancestor of a Binary Tree(Postorder)

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

Given the following binary tree: root = [3,5,1,6,2,0,8,null,null,7,4]

img

Example 1:

1
2
3
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1
Output: 3
Explanation: The LCA of nodes 5 and 1 is 3.

Example 2:

1
2
3
Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4
Output: 5
Explanation: The LCA of nodes 5 and 4 is 5, since a node can be a descendant of itself according to the LCA definition.

Note:

  • All of the nodes’ values will be unique.
  • p and q are different and both values will exist in the binary tree.
1
2
3
4
5
6
7
8
9
10
11
12
13
//Preorder是从上到下,Postorder是从下到上
//typical, needs to be memorized
class Solution {
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null || root == p || root == q) return root;
TreeNode left = lowestCommonAncestor(root.left, p, q);
TreeNode right = lowestCommonAncestor(root.right, p, q);
if (left != null && right != null) {
return root;
}
return left == null ? right : left;//叶子节点,或者单子树节点
}
}

366. Find Leaves of Binary Tree(Postorder)付费题

找出BST中所有的叶子节点

[4, 5, 3] [2] [1]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public List<List<Integer>> findLeaves (TreeNode root) {
//有顺序,就要有一个level
List<List<Integer>> res = new ArrayList<>();
helper(res, root);
return res;
}
private int helper(List<List<Integer>> res, TreeNode root) {
if (root == null) return -1;
int left = helper(res, root.left);
int right = helper(res, root.right);
int level = Math.max(left, right) + 1;//叶子节点是第0层,因为叶子节点也有左右子树,都为0,为NULL层
if (res.size() == level) {
res.add(new ArrayList<>());
}
res.get(level).add(root.val);//将值加入对应层
root.left = null;
root.right = null;
return level;
}

树的专题

Preorder Inorder Postorder Levelorder
Recursion DFS DFS DFS DFS
Iteration Stack Stack Stack Queue

四种遍历模板

Preorder Inorder Postorder Levelorder
Recursion DFS DFS DFS Queue
特点 Stack BST 子模块 Queue

257.Binary Tree Paths

Given a binary tree, return all root-to-leaf paths.

Note: A leaf is a node with no children.

Example:

1
2
3
4
5
6
7
8
9
10
11
Input:

1
/ \
2 3
\
5

Output: ["1->2->5", "1->3"]

Explanation: All root-to-leaf paths are: 1->2->5, 1->3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//Preorder
//空间复杂度为O(h)
class Solution {
public List<String> binaryTreePaths(TreeNode root) {
List<String> res = new ArrayList<>();
if(root == null) return res;
helper(res, root, "");
return res;
}
public void helper(List<String> res, TreeNode root, String path) {
if (root.left == null && root.right == null) {
res.add(path + root.val);
}
if (root.left != null) {
//path一开始是”“,后来加入了"x->","y->""
helper(res, root.left, path + root.val + "->");
}
if (root.right != null) {
helper(res, root.right, path + root.val + "->");
}
}
}

113.Path Sum II

Given a binary tree and a sum, find all root-to-leaf paths where each path’s sum equals the given sum.

Note: A leaf is a node with no children.

Example:

Given the below binary tree and sum = 22,

1
2
3
4
5
6
7
      5
/ \
4 8
/ / \
11 13 4
/ \ / \
7 2 5 1

Return:

1
2
3
4
[
[5,4,11,2],
[5,8,4,5]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//PreOrder
//从上到下遍历,到最后一层截止即可。
class Solution {
public List<List<Integer>> pathSum(TreeNode root, int sum) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
helper(res, new ArrayList<>(), root, sum);
return res;
}
public void helper(List<List<Integer>> res, List<Integer> list ,TreeNode root, int sum) {
if (root == null) return;
list.add(root.val);
if (root.left == null && root.right == null) {
if (sum == root.val) {
res.add(new ArrayList<>(list));
}
}
helper(res, list, root.left, sum - root.val);
helper(res, list, root.right, sum - root.val);
list.remove(list.size() - 1);//删掉叶子节点,如果没有的话,List就会无限向后加,back trackiing
//然后在helper()执行完毕以后,向上遍历,并返回list.remove(),也就是看父节点的另外一个叶子节点
}
}

双PRE

298. Binary Tree Longest Consecutive Sequence(Preorder)(付费题)

找出二叉树中连续的最长序列(不能忽然从子树换到BST的另外一颗子树)

  • 要求返回值为连续最长序列的父节点
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//当前节点的值是前一个节点的值 + 1
//max:当前整体长度,最后去和res比较
//target:判断下一个数是否等于target
//max = 1走到这里的时候断了
private int res = 0;

public int longestConsecutive(TreeNode root) {
if (root == null) return 0;
helper(root, 0, root.val);
return res;
}

public void helper(TreeNode root, int max, int target) {
if (root == null) return;
if (root.val == target) {
max++;
} else max = 1;
res = Math.max(res, max);
helper(root.left, max, root.val + 1);
helper(root.right, max, root.val + 1);
}

100.Same Tree

Share

Given two binary trees, write a function to check if they are the same or not.

Two binary trees are considered the same if they are structurally identical and the nodes have the same value.

Example 1:

1
2
3
4
5
6
7
Input:     1         1
/ \ / \
2 3 2 3

[1,2,3], [1,2,3]

Output: true

Example 2:

1
2
3
4
5
6
7
Input:     1         1
/ \
2 2

[1,2], [1,null,2]

Output: false

Example 3:

1
2
3
4
5
6
7
Input:     1         1
/ \ / \
2 1 1 2

[1,2,1], [1,1,2]

Output: false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isSameTree(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
}
}

101.Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

For example, this binary tree [1,2,2,3,4,4,3] is symmetric:

1
2
3
4
5
    1
/ \
2 2
/ \ / \
3 4 4 3

But the following [1,2,2,null,3,null,3] is not:

1
2
3
4
5
  1
/ \
2 2
\ \
3 3

Follow up: Solve it both recursively and iteratively.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//双PRE
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) return true;
return helper(root.left, root.right);
}
public boolean helper(TreeNode p, TreeNode q) {
if (p == null && q == null) return true;
if (p == null || q == null) return false;
if (p.val != q.val) return false;
//反过来,就变成100题了
return helper(p.left, q.right) && helper(p.right, q.left);
}
}

112. Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

Note: A leaf is a node with no children.

Example:

Given the below binary tree and sum = 22,

1
2
3
4
5
6
7
      5
/ \
4 8
/ / \
11 13 4
/ \ \
7 2 1

return true, as there exist a root-to-leaf path 5->4->11->2 which sum is 22.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean hasPathSum(TreeNode root, int sum) {
if (root == null) return false;
if(root.left == null && root.right == null) {
return root.val == sum;
}
//判断sum从root一直减下去的值是否等于那条路径的最终的叶子节点
//从上到下遍历,到最后一层截止即可。
return hasPathSum(root.left, sum - root.val) || hasPathSum(root.right, sum - root.val);
}
}

129. Sum Root to Leaf Numbers

Share

Given a binary tree containing digits from 0-9 only, each root-to-leaf path could represent a number.

An example is the root-to-leaf path 1->2->3 which represents the number 123.

Find the total sum of all root-to-leaf numbers.

Note: A leaf is a node with no children.

Example:

1
2
3
4
5
6
7
8
9
Input: [1,2,3]
1
/ \
2 3
Output: 25
Explanation:
The root-to-leaf path 1->2 represents the number 12.
The root-to-leaf path 1->3 represents the number 13.
Therefore, sum = 12 + 13 = 25.

Example 2:

1
2
3
4
5
6
7
8
9
10
11
12
Input: [4,9,0,5,1]
4
/ \
9 0
/ \
5 1
Output: 1026
Explanation:
The root-to-leaf path 4->9->5 represents the number 495.
The root-to-leaf path 4->9->1 represents the number 491.
The root-to-leaf path 4->0 represents the number 40.
Therefore, sum = 495 + 491 + 40 = 1026.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int sumNumbers(TreeNode root) {
return helper(root, 0);
}
public int helper(TreeNode root, int num) {
if (root == null) return 0;
if (root.left == null && root.right == null) {
return num * 10 + root.val;
}
return helper(root.left, num * 10 + root.val) +
helper(root.right, num * 10 + root.val);
}
}

111.Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

Note: A leaf is a node with no children.

Example:

Given binary tree [3,9,20,null,null,15,7],

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

return its minimum depth = 2.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public int minDepth(TreeNode root) {
if (root == null) return 0;
if (root.left == null || root.right == null) {
//case:只有一个子树
return Math.max(minDepth(root.left), minDepth(root.right)) + 1;//+1是因为层数是从下到上数到,最下层的起始层数应该为0
}
return Math.min(minDepth(root.left), minDepth(root.right)) + 1;
}
}

98.Validate Binary Search Tree

Given a binary tree, determine if it is a valid binary search tree (BST).

Assume a BST is defined as follows:

  • The left subtree of a node contains only nodes with keys less than the node’s key.
  • The right subtree of a node contains only nodes with keys greater than the node’s key.
  • Both the left and right subtrees must also be binary search trees.

Example 1:

1
2
3
4
5
6
    2
/ \
1 3

Input: [2,1,3]
Output: true

Example 2:

1
2
3
4
5
6
7
8
9
    5
/ \
1 4
/ \
3 6

Input: [5,1,4,null,null,3,6]
Output: false
Explanation: The root node's value is 5 but its right child's value is 4.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public boolean isValidBST(TreeNode root) {
if (root == null) return true;
return helper(root, null, null);
}
public static boolean helper(TreeNode root, Integer min, Integer max) {
if (root == null) return true;
if (min != null && root.val <= min) return false;
if (max != null && root.val >= max) return false;
return helper(root.left, min, root.val) && helper(root.right, root.val, max);
}
}

513. Find Bottom Left Tree Value

Given a binary tree, find the leftmost value in the last row of the tree.

Example 1:

1
2
3
4
5
6
7
8
Input:

2
/ \
1 3

Output:
1

Example 2:

1
2
3
4
5
6
7
8
9
10
11
12
Input:

1
/ \
2 3
/ / \
4 5 6
/
7

Output:
7

Note: You may assume the tree (i.e., the given root node) is not NULL.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
int res = 0;
int height = 0;//记录当前的高度
public int findBottomLeftValue(TreeNode root) {
if (root == null) return -1;
helper(root ,1);//1就是depth
return res;
}
public void helper(TreeNode root, int depth) {
if (root == null) return;
if (height < depth) {//没找到最下面就继续找
res = root.val;
height = depth;
}
helper(root.left, depth + 1);
helper(root.right, depth +1);
}
}

144.Binary Tree Preorder Traversal

Given a binary tree, return the preorder traversal of its nodes’ values.

Example:

1
2
3
4
5
6
7
8
Input: [1,null,2,3]
1
\
2
/
3

Output: [1,2,3]

Follow up: Recursive solution is trivial, could you do it iteratively?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
* @lc app=leetcode.cn id=144 lang=java
*
* [144] 二叉树的前序遍历
*/

// @lc code=start
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> preorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) return res;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
if (cur.right != null) stack.push(cur.right);
if (cur.left != null) stack.push(cur.left);
res.add(cur.val);
}
return res;
}
}
// @lc code=end
//recursion
// class Solution {
// public List<Integer> preorderTraversal(TreeNode root) {
// List<Integer> res = new ArrayList<>();
// if (root == null) return res;
// helper(res, root);
// return res;
// }
// public static void helper(List<Integer> res, TreeNode root) {
// if (root == null) return;
// res.add(root.val);
// helper(res, root.left);
// helper(res, root.right);
// }
// }

94.Binary Tree Inorder Traversal

Given a binary tree, return the inorder traversal of its nodes’ values.

Example:

1
2
3
4
5
6
7
8
Input: [1,null,2,3]
1
\
2
/
3

Output: [1,3,2]

Follow up: Recursive solution is trivial, could you do it iteratively?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
import java.util.List;

/*
* @lc app=leetcode.cn id=94 lang=java
*
* [94] 二叉树的中序遍历
*/

// @lc code=start
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> inorderTraversal(TreeNode root) {
List<Integer> res = new ArrayList<>();
if (root == null) return res;
Stack<TreeNode> stack = new Stack<>();
TreeNode cur = root;
while (cur != null || !stack.isEmpty()) {
while (cur != null) {
stack.push(cur);
cur = cur.left;
}
cur = stack.pop();
res.add(cur.val);
cur = cur.right;
}
return res;
}
}
// @lc code=end

// class Solution {
// public List<Integer> inorderTraversal(TreeNode root) {
// List<Integer> res = new ArrayList<>();
// if (root == null) return res;
// helper(res, root);
// return res;
// }
// public static void helper(List<Integer> res, TreeNode root) {
// if (root == null) return;
// helper(res, root.left);
// res.add(root.val);
// helper(res, root.right);
// }
// }

145.Binary Tree Postorder Traversal

Given a binary tree, return the postorder traversal of its nodes’ values.

Example:

1
2
3
4
5
6
7
8
Input: [1,null,2,3]
1
\
2
/
3

Output: [3,2,1]

Follow up: Recursive solution is trivial, could you do it iteratively?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import java.util.LinkedList;
import java.util.Stack;

/*
* @lc app=leetcode.cn id=145 lang=java
*
* [145] 二叉树的后序遍历
*/

// @lc code=start
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<Integer> postorderTraversal(TreeNode root) {
LinkedList<Integer> res = new LinkedList<>();
if (root == null) return res;
Stack<TreeNode> stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode cur = stack.pop();
res.addFirst(cur.val);//加头部的节点,倒着加
if(cur.left != null) stack.push(cur.left);
if(cur.right != null) stack.push(cur.right);
}
return res;
}
}
// @lc code=end

// class Solution {
// public List<Integer> inorderTraversal(TreeNode root) {
// List<Integer> res = new ArrayList<>();
// if (root == null) return res;
// helper(res, root);
// return res;
// }
// public static void helper(List<Integer> res, TreeNode root) {
// if (root == null) return;
// helper(res, root.left);
// res.add(root.val);
// helper(res, root.right);
// }
// }

102.Binary Tree Level Order Traversal

Given a binary tree, return the level order traversal of its nodes’ values. (ie, from left to right, level by level).

For example:
Given binary tree [3,9,20,null,null,15,7],

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

return its level order traversal as:

1
2
3
4
5
[
[3],
[9,20],
[15,7]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
/*
* @lc app=leetcode.cn id=102 lang=java
*
* [102] 二叉树的层序遍历
*/

// @lc code=start
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
// DFS思想
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
helper(res, root, 0);
return res;
}
public static void helper(List<List<Integer>> res, TreeNode root, int level) {
if (root == null) return;
if (level >= res.size()) {//到达单边子树的最高高度,level就不再增加
res.add(new ArrayList<>());
}
res.get(level).add(root.val);//最开始得到的level是0,然后将root的值3加进去
helper(res, root.left, level + 1);
helper(res, root.right, level + 1);
}
}
// @lc code=end

// class Solution {
// public List<List<Integer>> levelOrder(TreeNode root) {
// List<List<Integer>> res = new ArrayList<>();
// if (root == null) return res;
// Queue<TreeNode> queue = new LinkedList<>();
// queue.offer(root);
// while(!queue.isEmpty()) {
// int size = queue.size();//size有层次控制的作用,类似滑动窗口的效果,每次只能有2个或者1个Node被处理
// List<Integer> list = new ArrayList<>();
// for (int i = 0; i < size; i++) {
// TreeNode cur = queue.poll();
// if(cur.left != null) queue.offer(cur.left);
// if(cur.right != null) queue.offer(cur.right);
// list.add(cur.val);
// }
// res.add(list);
// }
// return res;
// }
// }

107.Binary Tree Level Order Traversal II

Given a binary tree, return the bottom-up level order traversal of its nodes’ values. (ie, from left to right, level by level from leaf to root).

For example:
Given binary tree [3,9,20,null,null,15,7],

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

return its bottom-up level order traversal as:

1
2
3
4
5
[
[15,7],
[9,20],
[3]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
* @lc app=leetcode.cn id=107 lang=java
*
* [107] 二叉树的层次遍历 II
*/

// @lc code=start
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
//BFS的思想
class Solution {
public List<List<Integer>> levelOrderBottom(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
while (!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode cur = queue.poll();
if(cur.left != null) queue.offer(cur.left);
if(cur.right != null) queue.offer(cur.right);
list.add(cur.val);
}
res.add(0, list);
}
return res;
}
}
// @lc code=end




// class Solution {
// public List<List<Integer>> levelOrder(TreeNode root) {
// List<List<Integer>> res = new ArrayList<>();
// if (root == null) return res;
// helper(res, root, 0);
// return res;
// }
// public static void helper(List<List<Integer>> res, TreeNode root, int level) {
// if (root == null) return;
// if (level >= res.size()) {//到达单边子树的最高高度,level就不再增加
// res.add(0, new ArrayList<>());//因为是倒序,所以向前查
// }
// res.get(res.size() - level - 1).add(root.val);
// //,在上一部,res加入一个arraylist,变成了1
// //之前index为0, 1 - 0 - 1才到root为3的地方
// helper(res, root.left, level + 1);
// helper(res, root.right, level + 1);
// }
// }

103.Binary Tree Zigzag Level Order Traversal

Given a binary tree, return the zigzag level order traversal of its nodes’ values. (ie, from left to right, then right to left for the next level and alternate between).

For example:
Given binary tree [3,9,20,null,null,15,7],

1
2
3
4
5
  3
/ \
9 20
/ \
15 7

return its zigzag level order traversal as:

1
2
3
4
5
[
[3],
[20,9],
[15,7]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode(int x) { val = x; }
* }
*/
class Solution {
public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if (root == null) return res;
Queue<TreeNode> queue = new LinkedList<>();
queue.offer(root);
boolean x = true;
while(!queue.isEmpty()) {
int size = queue.size();
List<Integer> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
TreeNode cur = queue.poll();
if (x) {
list.add(cur.val);//在第二次执行时,就执行这个,
} else {
list.add(0, cur.val);//因为true = true的结果是对的, 所以就是false,进来就执行这个,不断的从尾加
}
if(cur.left != null) queue.offer(cur.left);
if(cur.right != null) queue.offer(cur.right);
}
res.add(list);
x = x ? false : true;
}
return res;
}
}

228.Summary Ranges

Given a sorted integer array without duplicates, return the summary of its ranges.

Example 1:

1
2
3
Input:  [0,1,2,4,5,7]
Output: ["0->2","4->5","7"]
Explanation: 0,1,2 form a continuous range; 4,5 form a continuous range.

Example 2:

1
2
3
Input:  [0,2,3,4,6,8,9]
Output: ["0","2->4","6","8->9"]
Explanation: 2,3,4 form a continuous range; 8,9 form a continuous range.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public List<String> summaryRanges(int[] nums) {
List<String> res = new ArrayList<>();
if (nums == null || nums.length == 0) return res;
for (int i = 0; i < nums.length; i++) {
int num = nums[i];
while (i < nums.length - 1 && nums[i] + 1 == nums[i + 1]) {
i++;
}
if(num != nums[i]) {
res.add(num + "->" + nums[i]);//起点就终点
} else {
res.add(num + "");//代表只有一个数
}
}
return res;
}
}

6.Zigzag Conversion

The string "PAYPALISHIRING" is written in a zigzag pattern on a given number of rows like this: (you may want to display this pattern in a fixed font for better legibility)

1
2
3
P   A   H   N
A P L S I I G
Y I R

And then read line by line: "PAHNAPLSIIGYIR"

Write the code that will take a string and make this conversion given a number of rows:

1
string convert(string s, int numRows);

Example 1:

1
2
Input: s = "PAYPALISHIRING", numRows = 3
Output: "PAHNAPLSIIGYIR"

Example 2:

1
2
3
4
5
6
7
8
Input: s = "PAYPALISHIRING", numRows = 4
Output: "PINALSIGYAHRPI"
Explanation:

P I N
A L S I G
Y A H R
P I
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public String convert(String s, int numRows) {
if (numRows <= 1) return s;
StringBuilder[] sb = new StringBuilder[numRows];
for(int i = 0; i < sb.length; i++) {
sb[i] = new StringBuilder("");
}
for (int i = 0; i < s.length(); i++) {
int index = i % (2 * numRows - 2);
index = index < numRows ? index : 2 * numRows - 2 - index;
sb[index].append(s.charAt(i));
}
for (int i = 1; i < sb.length; i++) {
sb[0].append(sb[i]);
}
return sb[0].toString();
}
}

179.Largest Number

Given a list of non negative integers, arrange them such that they form the largest number.

Example 1:

1
2
Input: [10,2]
Output: "210"

Example 2:

1
2
Input: [3,30,34,5,9]
Output: "9534330"

Note: The result may be very large, so you need to return a string instead of an integer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Solution {
public String largestNumber(int[] nums) {
if (nums == null || nums.length == 0) return "";
String[] res = new String[nums.length];
for (int i = 0; i < nums.length; i++) {
res[i] = String.valueOf(nums[i]);//类型转换
}
Arrays.sort(res, new Comparator<String>(){
@Override
public int compare(String str1, String str2) {
String s1 = str1 + str2;
String s2 = str2 + str1;
return s2.compareTo(s1);
}
});//默认是从小到大排,这里需要重写函数
if (res[0].charAt(0) == '0') {
return "0";
}
StringBuilder sb = new StringBuilder();
for(String s : res) {
sb.append(s);
}
return sb.toString();
}
}

412.Fizz Buzz

Write a program that outputs the string representation of numbers from 1 to n.

But for multiples of three it should output “Fizz” instead of the number and for the multiples of five output “Buzz”. For numbers which are multiples of both three and five output “FizzBuzz”.

Example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
n = 15,

Return:
[
"1",
"2",
"Fizz",
"4",
"Buzz",
"Fizz",
"7",
"8",
"Fizz",
"Buzz",
"11",
"Fizz",
"13",
"14",
"FizzBuzz"
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public List<String> fizzBuzz(int n) {
List<String> res = new ArrayList<>();
if (n == 0) return res;
for (int i = 1; i <= n; i++) {
if (i % 3 == 0 && i % 5 == 0) {
res.add("FizzBuzz");
} else if (i % 3 == 0) {
res.add("Fizz");
} else if (i % 5 == 0) {
res.add("Buzz");
} else {
res.add(String.valueOf(i));
}
}
return res;
}
}

位运算及贪心思想(局部最优)。

125. Valid Palindrome(Palindrome)

Given a string, determine if it is a palindrome, considering only alphanumeric characters and ignoring cases.

Note: For the purpose of this problem, we define empty string as valid palindrome.

Example 1:

1
2
Input: "A man, a plan, a canal: Panama"
Output: true

Example 2:

1
2
Input: "race a car"
Output: false

Constraints:

  • s consists only of printable ASCII characters.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public boolean isPalindrome(String s) {
if (s == null || s.length() == 0) return true;
int left = 0;
int right = s.length() - 1;
//判断里面是否为数字或者字母
while (left < right) {
while (left < right && !Character.isLetterOrDigit(s.charAt(left))) {
left++;
}
while (left < right && !Character.isLetterOrDigit(s.charAt(right))) {
right--;
}
if (Character.toLowerCase(s.charAt(left)) != Character.toLowerCase(s.charAt(right))) {
return false;
}
left++;
right--;
}
return true;
}
}

260. Single Number III

Given an array of numbers nums, in which exactly two elements appear only once and all the other elements appear exactly twice. Find the two elements that appear only once.

Example:

1
2
Input:  [1,2,1,3,2,5]
Output: [3,5]

Note:

  1. The order of the result is not important. So in the above example, [5, 3] is also correct.
  2. Your algorithm should run in linear runtime complexity. Could you implement it using only constant space complexity?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//位运算
// A B :二进制数字有且至少有一位是不同的
class Solution {
public int[] singleNumber(int[] nums) {
int diff = 0;
for (int num : nums) {
diff ^= num;//出现两次,相同为0,不同为1 3^5 =(110) -6,负数是用二进制的补码形式来表示,
}
diff &= -diff;//把不同的位取出来(负数是二进制的补码)
int[] res = new int[2];
for (int num : nums) {
if ((num & diff) == 0) {
res[0] ^= num;
} else {
res[1] ^= num;XWXW
}
}
return res;
}
}

32. Longest Valid Parentheses(Parentheses

Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring.

Example 1:

1
2
3
Input: "(()"
Output: 2
Explanation: The longest valid parentheses substring is "()"

Example 2:

1
2
3
Input: ")()())"
Output: 4
Explanation: The longest valid parentheses substring is "()()"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Solution {
public int longestValidParentheses(String s) {
Stack<Integer> stack = new Stack<>();
int res = 0;
int start = -1;//把左括号的起点放入Stack中,把index=0的括号前面的位置记录一下,可以把0位也包含进去
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '(') {
stack.push(i);
} else {
if (stack.isEmpty()) {
start = i;//左括号就记录起点位置,右括号开头就把i给Start
} else {
stack.pop();//不需要记录pop出来的位置,因为是求最长的substring,知道起始位置就行
if (stack.isEmpty()) {
//前面的已经pop出来了()()
res = Math.max(res, i - start);//start存的是有效值的前一位,有效数组遍历是从0开始的,所以不用进行加一的操作
} else {
//case:(()),pop出来了,但是stack还有一个前面的(,匹配到内部()是合法的
res = Math.max(res, i - stack.peek());//stack中有一个以上个的值(括号的index), 把当前括号和紧随的左括号pick出来
}
}
}
}
return res;
}
}

22. Generate Parentheses(Parentheses)

Given n pairs of parentheses, write a function to generate all combinations of well-formed parentheses.

For example, given n = 3, a solution set is:

1
2
3
4
5
6
7
[
"((()))",
"(()())",
"(())()",
"()(())",
"()()()"
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//时间复杂度4^n / 根号n 
//backtracking方法
class Solution {
public List<String> generateParenthesis(int n) {
List<String> res = new ArrayList<>();
if (n == 0) return res;
helper(res, "", n, n);//左括号和右括号都有n个,为空是因为string里面一开始什么都没有
return res;
}
public void helper(List<String> res, String s, int left, int right) {
if (left > right) {//开头是)()(是不合法的
return;//())不合法
}
if (left == 0 && right == 0) {
res.add(s);
return;
}
if (left > 0) {
helper(res, s + "(", left - 1, right);
}
if (right > 0) {
helper(res, s + ")", left, right - 1);
}
}
}

137. Single Number II

Given a non-empty array of integers, every element appears three times except for one, which appears exactly once. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

1
2
Input: [2,2,3,2]
Output: 3

Example 2:

1
2
Input: [0,1,0,1,0,1,99]
Output: 99
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
/*
* @lc app=leetcode.cn id=137 lang=java
*
* [137] 只出现一次的数字 II
*
* 0-> 1 ->2-> 0 出现第一和第二次的时候记录一下,
* 00 ->01 ->10 ->00从 0 1 2 3(3置换为0)
* 00 ->10 ->01 ->00从 0 1 2 3(3置换为0)将上面的01和10转换了位置(这是一种做题的思路)
*
* ones twos
* 0 0
* 0->1 0->0
* 1->0 0->1
* 0->0 1->0
*/

// @lc code=start
//如果只有一个数就是从0到1的过程
/*
* 1,讲结果存入Ones里(如果只有一个数,就直接存入Ones,并返回)
* 2,清空Ones,存入twos
* 3,清空twos
*/
class Solution {
//出现3次后,% 3 = 0,所以在出现第三次时,将其置为0
public int singleNumber(int[] nums) {
int ones = 0, twos = 0;
for (int i = 0; i < nums.length; i++) {
ones = (ones ^ nums[i]) & ~twos;//~为取反符号
twos = (twos ^ nums[i]) & ~ones;
}
return ones;
}
}
// @lc code=end

// class Solution {
// public int singleNumber(int[] nums) {
// HashMap<Integer, Integer> hashmap = new HashMap<>();
// for (int num : nums)
// hashmap.put(num, hashmap.getOrDefault(num, 0) + 1);
// //当Map集合中有这个key时,就使用这个key值,如果没有就使用默认值defaultValue
// for (int k : hashmap.keySet())
// if (hashmap.get(k) == 1) return k;
// return -1;
// }
// }

55. Jump Game(基础)

Given an array of non-negative integers, you are initially positioned at the first index of the array.

Each element in the array represents your maximum jump length at that position.

Determine if you are able to reach the last index.

Example 1:

1
2
3
Input: nums = [2,3,1,1,4]
Output: true
Explanation: Jump 1 step from index 0 to 1, then 3 steps to the last index.

Example 2:

1
2
3
Input: nums = [3,2,1,0,4]
Output: false
Explanation: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.

Constraints:

  • 1 <= nums.length <= 3 * 10^4
  • 0 <= nums[i][j] <= 10^5
1
2
3
4
5
6
7
8
9
10
11
12
13
//greedy 贪心思想
//max代表当前能跳的最大步数
class Solution {
public boolean canJump(int[] nums) {
int max = 0;//max代表当前能跳的最大步数

for (int i = 0; i < nums.length; i++) {
if (i > max) return false;
max = Math.max(nums[i] + i, max);
}
return true;
}
}

135. Candy(基础)

There are N children standing in a line. Each child is assigned a rating value.

You are giving candies to these children subjected to the following requirements:

  • Each child must have at least one candy.
  • Children with a higher rating get more candies than their neighbors.

What is the minimum candies you must give?

Example 1:

1
2
3
Input: [1,0,2]
Output: 5
Explanation: You can allocate to the first, second and third child with 2, 1, 2 candies respectively.

Example 2:

1
2
3
4
Input: [1,2,2]
Output: 4
Explanation: You can allocate to the first, second and third child with 1, 2, 1 candies respectively.
The third child gets 1 candy because it satisfies the above two conditions.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
/*
* @lc app=leetcode.cn id=135 lang=java
*
* [135] 分发糖果
*/

// @lc code=start
//贪心
// 从左到右遍历,使得右边评分更高的元素比左边至少多于1个糖果
// 从右到左遍历,使得左边评分更高的元素比右边至少多于1个糖果
import java.util.*;
class Solution {
public int candy(int[] ratings) {
if (ratings.length == 0) return 0;
//[4, 5, 1]从左到友,多给右面一个,然后从右到左,可能已经比左面大了,所以不需要给
int[] candies = new int[ratings.length];
Arrays.fill(candies, 1);

for (int i = 1; i < candies.length; i++) {
// -1是倒数第一个元素,每次要前跟后比
if (ratings[i] > ratings[i - 1]) {
candies[i] = candies[i - 1] + 1;
}
}
// -1是倒数第一个元素,每次要前跟后比
for (int i = candies.length - 2; i >= 0; i--) {
if (ratings[i] > ratings[i + 1]) {
candies[i] = Math.max(candies[i], candies[i + 1] + 1);
}
}
int res = 0;
for (int candy : candies) {
res += candy;
}
return res;
}
}
// @lc code=end

121. Best Time to Buy and Sell Stock(实现题)

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.

Note that you cannot sell a stock before you buy one.

Example 1:

1
2
3
4
Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.

Example 2:

1
2
3
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* @lc app=leetcode.cn id=121 lang=java
*
* [121] 买卖股票的最佳时机
*/

// @lc code=start
class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length < 2) return 0;
int min = prices[0];
int profit = 0;
for (int price :prices) {
min = Math.min(min, price);
profit = Math.max(profit, price - min);
}
return profit;
}
}
// [7,1,5,3,6,4]
// Answer 7 Expected Answer 5

// @lc code=end

122. Best Time to Buy and Sell Stock II(实现题)

Say you have an array prices for which the ith element is the price of a given stock on day i.

Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).

Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).

Example 1:

1
2
3
4
Input: [7,1,5,3,6,4]
Output: 7
Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.

Example 2:

1
2
3
4
5
Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
engaging multiple transactions at the same time. You must sell before buying again.

Example 3:

1
2
3
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.

Constraints:

  • 1 <= prices.length <= 3 * 10 ^ 4
  • 0 <= prices[i] <= 10 ^ 4
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
/*
* @lc app=leetcode.cn id=122 lang=java
*
* [122] 买卖股票的最佳时机 II
*/

// @lc code=start
class Solution {
public int maxProfit(int[] prices) {
if (prices == null || prices.length < 2) {
return 0;
}
int profit = 0;
for (int i = 1; i < prices.length; i++) {
if (prices[i] > prices[i - 1]) {
profit += prices[i] - prices[i - 1];
}
}
return profit;
}
}
// @lc code=end

89. Gray Code

The gray code is a binary numeral system where two successive values differ in only one bit.

Given a non-negative integer n representing the total number of bits in the code, print the sequence of gray code. A gray code sequence must begin with 0.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Input: 2
Output: [0,1,3,2]
Explanation:
00 - 0
01 - 1
11 - 3
10 - 2

For a given n, a gray code sequence may not be uniquely defined.
For example, [0,2,3,1] is also a valid gray code sequence.

00 - 0
10 - 2
11 - 3
01 - 1

Example 2:

1
2
3
4
5
Input: 0
Output: [0]
Explanation: We define the gray code sequence to begin with 0.
A gray code sequence of n has size = 2n, which for n = 0 the size is 20 = 1.
Therefore, for n = 0 the gray code sequence is [0].
1
2
3
4
5
6
7
8
9
10
11
12
13
// @lc code=start
//公式 g(i) = i ^ (i / 2)
import java.util.List;
class Solution {
public List<Integer> grayCode(int n) {
List<Integer> res = new ArrayList<>();
//0001左移两位变成0100 = 4,左移三位等于8
for (int i = 0; i < 1 << n; i++) {
res.add(i ^ i >> 1);//除以2
}
return res;
}
}

155. Min Stack

Design a stack that supports push, pop, top, and retrieving the minimum element in constant time.

  • push(x) – Push element x onto stack.
  • pop() – Removes the element on top of the stack.
  • top() – Get the top element.
  • getMin() – Retrieve the minimum element in the stack.

Example 1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Input
["MinStack","push","push","push","getMin","pop","top","getMin"]
[[],[-2],[0],[-3],[],[],[],[]]

Output
[null,null,null,null,-3,null,0,-2]

Explanation
MinStack minStack = new MinStack();
minStack.push(-2);
minStack.push(0);
minStack.push(-3);
minStack.getMin(); // return -3
minStack.pop();
minStack.top(); // return 0
minStack.getMin(); // return -2

Constraints:

  • Methods pop, top and getMin operations will always be called on non-empty stacks.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    /*
    * @lc app=leetcode.cn id=155 lang=java
    *
    * [155] 最小栈
    */

    // @lc code=start
    class MinStack {
    Stack<Integer> stack;
    int min;//Integer比较的是范围,是地址,Interger类型之间的比较应该用equals()
    /** initialize your data structure here. */
    public MinStack() {
    stack = new Stack<>();
    min = Integer.MAX_VALUE;//初始化Min
    }

    public void push(int x) {
    if (x <= min) {
    stack.push(min);
    min = x;
    }
    stack.push(x);
    }

    public void pop() {
    if (stack.pop() == min) {
    min = stack.pop();
    }
    }

    public int top() {
    return stack.peek();
    }

    public int getMin() {
    return min;
    }
    }

    /**
    * Your MinStack object will be instantiated and called as such:
    * MinStack obj = new MinStack();
    * obj.push(x);
    * obj.pop();
    * int param_3 = obj.top();
    * int param_4 = obj.getMin();
    */
    // @lc code=end

    // class MinStack {
    // private Stack<Integer> stack;
    // private Stack<Integer> minStack;
    // /** initialize your data structure here. */
    // public MinStack() {
    // stack = new Stack<>();
    // minStack = new Stack<>();
    // }

    // public void push(int x) {
    // stack.push(x);
    // if(!minStack.isEmpty()) {
    // int min = minStack.peek();
    // if(x <= min) {
    // minStack.push(x);
    // }
    // } else {
    // minStack.push(x);
    // }
    // }

    // public void pop() {
    // int x = stack.pop();
    // if(!minStack.isEmpty()) {
    // if(x == minStack.peek()) {
    // minStack.pop();
    // }
    // }
    // }

    // public int top() {
    // return stack.peek();
    // }

    // public int getMin() {
    // return minStack.peek();
    // }
    // }

232.Implement Queue using Stacks

Implement the following operations of a queue using stacks.

  • push(x) – Push element x to the back of queue.
  • pop() – Removes the element from in front of queue.
  • peek() – Get the front element.
  • empty() – Return whether the queue is empty.

Example:

1
2
3
4
5
6
7
MyQueue queue = new MyQueue();

queue.push(1);
queue.push(2);
queue.peek(); // returns 1
queue.pop(); // returns 1
queue.empty(); // returns false

Notes:

  • You must use only standard operations of a stack – which means only push to top, peek/pop from top, size, and is empty operations are valid.
  • Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
  • You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
没有的注释的为O(1)
/**
* Your MyQueue object will be instantiated and called as such:
* MyQueue obj = new MyQueue();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.peek();
* boolean param_4 = obj.empty();
*/

class MyQueue1 {
Stack<Integer> s1;
Stack<Integer> s2;
/** Initialize your data structure here. */
public MyQueue() {
s1 = new Stack();
s2 = new Stack();
}

/** Push element x to the back of queue. */
public void push(int x) {
s1.push(x);
}
//O(n)
/** Removes the element from in front of queue and returns that element. */
public int pop() {
//s1代表没进行过处理的,queue的反方向,则S2代表处理过的。
if(!s2.isEmpty()) return s2.pop();
else {
while (!s1.isEmpty()) s2.push(s1.pop());
return s2.pop();
}
}
//O(n)
/** Get the front element. */
public int peek() {
if(!s2.isEmpty()) return s2.peek();
else {
while(!s1.isEmpty()) s2.push(s1.pop());
return s2.peek();
}
}

/** Returns whether the queue is empty. */
public boolean empty() {
return s1.isEmpty() && s2.isEmpty();
}
}


//Methods 2
class MyQueue2 {
Stack<Integer> s1;
Stack<Integer> s2;
private int front;
/** Initialize your data structure here. */
public MyQueue() {
s1 = new Stack();
s2 = new Stack();
}

/** Push element x to the back of queue. */
//O(n)
public void push(int x) {
if (s1.isEmpty()) {
front = x;
}
while (!s1.isEmpty()) {
s2.push(s1.pop());
}
s2.push(x);
while (!s2.isEmpty()) {
s1.push(s2.pop());
}
}
/** Removes the element from in front of queue and returns that element. */
public int pop() {
//s1代表没进行过处理的,queue的反方向,则S2代表处理过的。
int res = s1.pop();
if(!s1.isEmpty()) {
front = s1.peek();
}
return res;
}
/** Get the front element. */
public int peek() {
return front;
}

/** Returns whether the queue is empty. */
public boolean empty() {
return s1.isEmpty();
}
}

225. Implement Stack using Queues

Implement the following operations of a stack using queues.

  • push(x) – Push element x onto stack.
  • pop() – Removes the element on top of the stack.
  • top() – Get the top element.
  • empty() – Return whether the stack is empty.

Example:

1
2
3
4
5
6
7
MyStack stack = new MyStack();

stack.push(1);
stack.push(2);
stack.top(); // returns 2
stack.pop(); // returns 2
stack.empty(); // returns false

Notes:

  • You must use only standard operations of a queue – which means only push to back, peek/pop from front, size, and is empty operations are valid.
  • Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
  • You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
* @lc app=leetcode.cn id=225 lang=java
*
* [225] 用队列实现栈
*/

// @lc code=start
import java.util.Queue;
import java.util.LinkedList;

class MyStack {
//queue 4321
//stack 1234
/** Initialize your data structure here. */
Queue<Integer> queue;
public MyStack() {
//前后开口,所以一个queue就可以实现
queue = new LinkedList<>();
}

/** Push element x onto stack. */
public void push(int x) {
queue.add(x);
for (int i = 0; i < queue.size() - 1; i++) {
queue.add(queue.poll());
}
}

/** Removes the element on top of the stack and returns that element. */
public int pop() {
return queue.poll();
}

/** Get the top element. */
public int top() {
return queue.peek();
}

/** Returns whether the stack is empty. */
public boolean empty() {
return queue.isEmpty();
}
}

/**
* Your MyStack object will be instantiated and called as such:
* MyStack obj = new MyStack();
* obj.push(x);
* int param_2 = obj.pop();
* int param_3 = obj.top();
* boolean param_4 = obj.empty();
*/
// @lc code=end

20. Valid Parentheses

Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid.

An input string is valid if:

  1. Open brackets must be closed by the same type of brackets.
  2. Open brackets must be closed in the correct order.

Note that an empty string is also considered valid.

Example 1:

1
2
Input: "()"
Output: true

Example 2:

1
2
Input: "()[]{}"
Output: true

Example 3:

1
2
Input: "(]"
Output: false

Example 4:

1
2
Input: "([)]"
Output: false

Example 5:

1
2
Input: "{[]}"
Output: true
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
/*
* @lc app=leetcode.cn id=20 lang=java
*
* [20] 有效的括号
*/

// @lc code=start
//case1 ()[]{}
//stack: pop value is )

class Solution {
public boolean isValid(String s) {
if (s.isEmpty())
return true;
Stack<Character> stack = new Stack<Character>();
for (char c:s.toCharArray()) {
if (c == '(')
stack.push(')');
else if (c == '{')
stack.push('}');
else if (c== '[')
stack.push(']');
else if(stack.isEmpty() || c != stack.pop())//当不为左括号时候,说明c是右括号,
//stack.pop弹出栈元素中存储的右括号元素,比较这两个右括号是否相等。
return false;
}
if (stack.isEmpty())//判断相对情况下的第一个字符是否为’),},】‘这种类型的。
//当stack为空时输入一个c=)时,stack内没有(与之对应,则认为false
return true;
return false;
}
}

150. Evaluate Reverse Polish Notation

Evaluate the value of an arithmetic expression in Reverse Polish Notation.

Valid operators are +, -, *, /. Each operand may be an integer or another expression.

Note:

  • Division between two integers should truncate toward zero.
  • The given RPN expression is always valid. That means the expression would always evaluate to a result and there won’t be any divide by zero operation.

Example 1:

1
2
3
Input: ["2", "1", "+", "3", "*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9

Example 2:

1
2
3
Input: ["4", "13", "5", "/", "+"]
Output: 6
Explanation: (4 + (13 / 5)) = 6

Example 3:

1
2
3
4
5
6
7
8
9
10
Input: ["10", "6", "9", "3", "+", "-11", "*", "/", "*", "17", "+", "5", "+"]
Output: 22
Explanation:
((10 * (6 / ((9 + 3) * -11))) + 17) + 5
= ((10 * (6 / (12 * -11))) + 17) + 5
= ((10 * (6 / -132)) + 17) + 5
= ((10 * 0) + 17) + 5
= (0 + 17) + 5
= 17 + 5
= 22

逆波兰表达式:

逆波兰表达式是一种后缀表达式,所谓后缀就是指算符写在后面。

  • 平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 )
  • 该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * )

逆波兰表达式主要有以下两个优点:

  • 去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + *也可以依据次序计算出正确结果。

  • 适合用栈操作运算:遇到数字则入栈;遇到算符则取出栈顶两个数字进行计算,并将结果压入栈中。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    /*
    * @lc app=leetcode.cn id=150 lang=java
    *
    * [150] 逆波兰表达式求值
    */

    // @lc code=start
    class Solution {
    public int evalRPN(String[] tokens) {
    Stack<Integer> stack = new Stack<>();
    for (String s : tokens) {
    if(s.equals("+")) {
    stack.push(stack.pop() + stack.pop());
    } else if (s.equals("-")) {
    int a = stack.pop();//先pop出来的数是减数
    int b = stack.pop();
    stack.push(b - a);
    } else if (s.equals("*")) {
    stack.push(stack.pop() * stack.pop());
    } else if (s.equals("/")) {
    int a = stack.pop();
    int b = stack.pop();
    stack.push(b / a);
    } else {
    stack.push(Integer.parseInt(s));//从String转为Int
    }
    }
    return stack.pop();
    }
    }
    // @lc code=end

224. Basic Calculator

Share

Implement a basic calculator to evaluate a simple expression string.

The expression string may contain open ( and closing parentheses ), the plus + or minus sign -, non-negative integers and empty spaces .

Example 1:

1
2
Input: "1 + 1"
Output: 2

Example 2:

1
2
Input: " 2-1 + 2 "
Output: 3

Example 3:

1
2
Input: "(1+(4+5+2)-3)+(6+8)"
Output: 23

Note:

  • You may assume that the given expression is always valid.
  • Do not use the eval built-in library function.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
* @lc app=leetcode.cn id=224 lang=java
*
* [224] 基本计算器
*/

// @lc code=start
class Solution {
public int calculate(String s) {
Stack<Integer> stack = new Stack<>();
int sign = 1;
int res = 0;
for (int i = 0; i < s.length(); i++) {
//判断当前是否为数字
if (Character.isDigit(s.charAt(i))) {
int num = s.charAt(i) - '0';
//判断下一位是不是还是数字,case:123
while (i + 1 < s.length() && Character.isDigit(s.charAt(i + 1))) {
num = num * 10 + s.charAt(i + 1) - '0';
i++;
}
res += num * sign;
} else if (s.charAt(i) == '+') {
sign = 1;
} else if (s.charAt(i) == '-') {
sign = -1;
} else if (s.charAt(i) == '(') {
//1 - 2可以看成 1 + (-2)
stack.push(res);
stack.push(sign);//sign会先Pop出来
//恢复到初始化状态
res = 0;
sign = 1;
} else if (s.charAt(i) == ')') {
res = res * stack.pop() + stack.pop();
}
}
return res;
}
}
// @lc code=end

161. One Edit Distance

字符串ST只差一个距离,返回True, 否则返回False

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
case1:abcre Abere

case2:abdc abc

case:3 abc abdc
//TIME O(n) Math.min(s,length(), t.length());
//Space:O(1) 因为substring虽然是O(n),但是只在return时候调用一次。

public static boolean isOneEditDistance(String s, String t) {
//case 1:找到第一个不同,让越过去,判断后面是否相同
//如果两个长度不等,取长的会越界,所以用Math.min()
for (int i = 0; i < Math.min(s,length(), t.length()); i++) {
if (s.charAt(i) != t.charAt(i)) {
if (s.length() == t.length()) {
return s.substring(i + 1).equals(t.substring(i + 1));
} else if (s.length() > t.length()) {
return s.substring(i + 1).equals(t.substring(i));
} else {
return t.substring(i + 1).equals(s.substring(i));
}
}
// abc和abcdef,在这里判断是不是只多1个,还是多了几个
return Math.abs(s.length() - t.length()) == 1;
}
}

168. Excel Sheet Column Title

Given a positive integer, return its corresponding column title as appear in an Excel sheet.

For example:

1
2
3
4
5
6
7
8
1 -> A
2 -> B
3 -> C
...
26 -> Z
27 -> AA
28 -> AB
...

Example 1:

1
2
Input: 1
Output: "A"

Example 2:

1
2
Input: 28
Output: "AB"

Example 3:

1
2
Input: 701
Output: "ZY"
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
* @lc app=leetcode.cn id=168 lang=java
*
* [168] Excel表列名称
*/

// @lc code=start
// 26Z 27AA 28AB,这里是对26的一个循环, 用%26+ 'A'算, 在26之后用/的方法
//time O(n) logN因为是/26
// Space O(n) 对应n,每次加一个字母

class Solution {
public String convertToTitle(int n) {
StringBuilder sb = new StringBuilder();
while (n > 0) {
n--;//28 % 26 = 2 + 'A' = 2 + 1 = 3 = 'C',所以Index要从0开始,但是这里对应的是A=1
sb.append((char)('A' + n % 26));
n /= 26;
}
return sb.reverse().toString();//得到的结果是反过来的
}
}
// @lc code=end

171. Excel Sheet Column Number

Given a column title as appear in an Excel sheet, return its corresponding column number.

For example:

1
2
3
4
5
6
7
8
A -> 1
B -> 2
C -> 3
...
Z -> 26
AA -> 27
AB -> 28
...

Example 1:

1
2
Input: "A"
Output: 1

Example 2:

1
2
Input: "AB"
Output: 28

Example 3:

1
2
Input: "ZY"
Output: 701
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
/*
* @lc app=leetcode.cn id=171 lang=java
*
* [171] Excel表列序号
*/

// @lc code=start
class Solution {
public int titleToNumber(String s) {
int res = 0;
for (int i = 0; i < s.length(); i++) {
res = res * 26 + (s.charAt(i) - 'A' + 1);//A对应的是1
}
return res;
}
}
// @lc code=end

38. Count and Say

The count-and-say sequence is the sequence of integers with the first five terms as following:

1
2
3
4
5
1.     1
2. 11
3. 21
4. 1211
5. 111221

1 is read off as "one 1" or 11.
11 is read off as "two 1s" or 21.
21 is read off as "one 2, then one 1" or 1211.

Given an integer n where 1 ≤ n ≤ 30, generate the nth term of the count-and-say sequence. You can do so recursively, in other words from the previous member read off the digits, counting the number of digits in groups of the same digit.

Note: Each term of the sequence of integers will be represented as a string.

Example 1:

1
2
3
Input: 1
Output: "1"
Explanation: This is the base case.

Example 2:

1
2
3
Input: 4
Output: "1211"
Explanation: For n = 3 the term was "21" in which we have two groups "2" and "1", "2" can be read as "12" which means frequency = 1 and value = 2, the same way "1" is read as "11", so the answer is the concatenation of "12" and "11" which is "1211".
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
/*
* @lc app=leetcode.cn id=38 lang=java
*
* [38] 外观数列
*/

// @lc code=start
class Solution {
/**
* 解题思路:
* 本题的难点在于:报数的概念理解,至少我从题意中没有很清晰的理解,但是感觉像是个递推式
* 从4->5分析,将4个每一位拆开看(个数+数字),4=1211 => 1=11,2=12,11=21,所以5=111221
* 所以解题用循环,从1->n可求解出来
*
* @param n
* @return
*/
public String countAndSay(int n) {
String str = "1";
for (int i = 2; i <= n; i++) {
StringBuilder builder = new StringBuilder();
char pre = str.charAt(0);
int count = 1;
for (int j = 1; j < str.length(); j++) {
char c = str.charAt(j);
if (c == pre) {
count++;
} else {
builder.append(count).append(pre);
pre = c;
count = 1;
}
}
builder.append(count).append(pre);
str = builder.toString();
}

return str;
}
}
// @lc code=end

75. Sort Colors

Given an array with n objects colored red, white or blue, sort them in-place so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note: You are not suppose to use the library’s sort function for this problem.

Example:

1
2
Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]

Follow up:

  • A rather straight forward solution is a two-pass algorithm using counting sort.
    First, iterate the array counting number of 0’s, 1’s, and 2’s, then overwrite array with total number of 0’s, then 1’s and followed by 2’s.
  • Could you come up with a one-pass algorithm using only constant space?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class Solution {
public void sortColors(int[] nums) {
if (nums == null || nums.length == 0) return;
//left控制0最后出现的位置,right控制1最开始出现的位置(倒序)
int left = 0;
int right = nums.length - 1;
int index = 0;
while (index <= right) {
if(nums[index] == 0) {
swap(nums, index++, left++);//原地交换
} else if(nums[index] == 1) {
index++;//不动
} else {
swap(nums, index, right--);//
}
}
}

public void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}

88. Merge Sorted Array

Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array.

Note:

  • The number of elements initialized in nums1 and nums2 are m and n respectively.
  • You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2.

Example:

1
2
3
4
5
Input:
nums1 = [1,2,3,0,0,0], m = 3
nums2 = [2,5,6], n = 3

Output: [1,2,2,3,5,6]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public void merge(int[] nums1, int m, int[] nums2, int n) {
int i = m - 1;
int j = n - 1;
int k = m + n - 1;
while (i >= 0 && j >= 0) {
//nums1和2都是排过序的,从后向前放,最大的放在最后
nums1[k--] = nums1[i] >= nums2[j] ? nums1[i--] : nums2[j--];
}
while (j >= 0) {
nums1[k--] = nums2[j--];
//i到极限,但是j还有剩余
}
}
}

189. Rotate Array

Given an array, rotate the array to the right by k steps, where k is non-negative.

Follow up:

  • Try to come up as many solutions as you can, there are at least 3 different ways to solve this problem.
  • Could you do it in-place with O(1) extra space?

Example 1:

1
2
3
4
5
6
Input: nums = [1,2,3,4,5,6,7], k = 3
Output: [5,6,7,1,2,3,4]
Explanation:
rotate 1 steps to the right: [7,1,2,3,4,5,6]
rotate 2 steps to the right: [6,7,1,2,3,4,5]
rotate 3 steps to the right: [5,6,7,1,2,3,4]

Example 2:

1
2
3
4
5
Input: nums = [-1,-100,3,99], k = 2
Output: [3,99,-1,-100]
Explanation:
rotate 1 steps to the right: [99,-1,-100,3]
rotate 2 steps to the right: [3,99,-1,-100]

Constraints:

  • 1 <= nums.length <= 2 * 10^4
  • It’s guaranteed that nums[i] fits in a 32 bit-signed integer.
  • k >= 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// time O(n),虽然三次翻转,但是没有累乘的操作
class Solution {
public void rotate(int[] nums, int k) {
//三次翻转
k %= nums.length;
reverse(nums, 0, nums.length - 1);//整体翻转
reverse(nums, 0, k - 1);//翻转前k
reverse(nums, k, nums.length - 1);//翻转剩下的n - k
}
public void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start++] = nums[end];
nums[end--] = temp;
}
}
}
// @lc code=end

// class Solution {
// public void rotate(int[] nums, int k) {
// int[] temp = new int[nums.length];
// for (int i = 0; i < nums.length; i++) {
// //如果K = 10,轮了一圈再往前轮三个,大于nums.length, 一开始i = 0, k = 3,把i当前的数给三这个位置
// //[1 ,2, 3, 4, 5, 6, 7],因为0 + 3 % 7 = 3
// // 1
// temp[(i + k) % nums.length] = nums[i];
// }
// //返回的是空,所以在原有的基础上操作,重新赋值
// //上面得到的结果存在temp里,要重新赋值
// for (int i = 0; i < nums.length; i++) {
// nums[i] = temp[i];
// }
// }
// }

41. First Missing Positive

Given an unsorted integer array, find the smallest missing positive integer.

Example 1:

1
2
Input: [1,2,0]
Output: 3

Example 2:

1
2
Input: [3,4,-1,1]
Output: 2

Example 3:

1
2
Input: [7,8,9,11,12]
Output: 1

Note:

Your algorithm should run in O(n) time and uses constant extra space.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//Bucket Sort
// [1 ,2, 0] index + 1
// [3, 4, -1, 1] 判断数是否大于0
// [1, 99, 3, 4]太大
// nums[nums[i] - 1] != nums[i] [3, 4, 1, 3] i = 0 nums[0] = 3,
// nums[nums[i] - 1]就是当前的数应该放在的位置上 nums[0] = 3 - 1 = 2 -> nums[2]= -1 != nums[i]=3
class Solution {
public int firstMissingPositive(int[] nums) {
if (nums == null || nums.length == 0) return 1;//输出的是最小的正整数
for (int i = 0; i < nums.length; i++) {
//这里是while,不是if [3, 1, 4, -1],if是单次
while (nums[i] > 0 && nums[i] <= nums.length && nums[nums[i] - 1] != nums[i]) {
int temp = nums[nums[i] - 1];
nums[nums[i] - 1] = nums[i];
nums[i] = temp;
}
}
for (int i = 0; i < nums.length; i++) {
if(nums[i] != i + 1) {
return i + 1;
}
}
return nums.length + 1;
}
}

66. Plus One

Given a non-empty array of digits representing a non-negative integer, plus one to the integer.

The digits are stored such that the most significant digit is at the head of the list, and each element in the array contain a single digit.

You may assume the integer does not contain any leading zero, except the number 0 itself.

Example 1:

1
2
3
Input: [1,2,3]
Output: [1,2,4]
Explanation: The array represents the integer 123.

Example 2:

1
2
3
Input: [4,3,2,1]
Output: [4,3,2,2]
Explanation: The array represents the integer 4321.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//case1 1011 1012
//case2 1099 1100
//case3 9999 10000

//time : O(n)
//space : O(n)在最后开辟了一个新的数组
class Solution {
public int[] plusOne(int[] digits) {
if (digits == null || digits.length == 0) return digits;
for (int i = digits.length - 1; i >= 0; i--) {
//case 1
if(digits[i] < 9) {
digits[i]++;
return digits;
} else {
//case2
digits[i] = 0;
}
}
//case 3
int[] res = new int[digits.length + 1];
res[0] = 1;
return res;
}
}

136. Single Number

Given a non-empty array of integers, every element appears twice except for one. Find that single one.

Note:

Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Example 1:

1
2
Input: [2,2,1]
Output: 1

Example 2:

1
2
Input: [4,1,2,1,2]
Output: 4
1
2
3
4
5
6
7
8
9
class Solution {
public int singleNumber(int[] nums) {
int res = 0;
for (int i = 0; i < nums.length; i++) {
res ^= nums[i];
}
return res;
}
}

🐘异或:相同为0,不同为1

389. Find The Difference

Given two strings s\ and t\ which consist of only lowercase letters.

String t\ is generated by random shuffling string s\ and then add one more letter at a random position.

Find the letter that was added in t\.

Example:

1
2
3
4
5
6
7
8
9
Input:
s = "abcd"
t = "abcde"

Output:
e

Explanation:
'e' is the letter that was added.
1
2
3
4
5
6
7
8
9
10
11
12
//性质:4与6进行异或的结果,再与4进行异或,得到了6.
class Solution {
public char findTheDifference(String s, String t) {
//t的长度比s长,所以直接取t的最后一位
char c = t.charAt(t.length() - 1);
for (int i = 0; i < s.length(); i++) {
c ^= s.charAt(i);
c ^= t.charAt(i);
}
return c;
}
}

性质(1):4与6进行异或的结果,再与4进行异或,得到了6.

191. Number of 1 Bits

Write a function that takes an unsigned integer and return the number of ‘1’ bits it has (also known as the Hamming weight).

Example 1:

1
2
3
Input: 00000000000000000000000000001011
Output: 3
Explanation: The input binary string 00000000000000000000000000001011 has a total of three '1' bits.

Example 2:

1
2
3
Input: 00000000000000000000000010000000
Output: 1
Explanation: The input binary string 00000000000000000000000010000000 has a total of one '1' bit.

Example 3:

1
2
3
Input: 11111111111111111111111111111101
Output: 31
Explanation: The input binary string 11111111111111111111111111111101 has a total of thirty one '1' bits.

Note:

  • Note that in some languages such as Java, there is no unsigned integer type. In this case, the input will be given as signed integer type and should not affect your implementation, as the internal binary representation of the integer is the same whether it is signed or unsigned.
  • In Java, the compiler represents the signed integers using 2’s complement notation. Therefore, in Example 3 above the input represents the signed integer -3.

Follow up:

If this function is called many times, how would you optimize it?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
//dp,前N个数的和就是它的DP值
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
dp[0] = nums[0];
int res = nums[0];
for(int i = 1; i < nums.length; i++) {
dp[i] = nums[i] + (dp[i - 1] < 0 ? 0 : dp[i - 1]);
res = Math.max(res, dp[i]);
}
return res;
}
}
// @lc code=end

// class Solution {
// //dp,前N个数的和就是它的DP值
// public int maxSubArray(int[] nums) {
// int[] dp = new int[nums.length];
// dp[0] = nums[0];
// int res = nums[0];
// for(int i = 1; i < nums.length; i++) {
// dp[i] = nums[i] + (dp[i - 1] < 0 ? 0 : dp[i - 1]);
// res = Math.max(res, dp[i]);
// }
// return res;
// }
// }

性质(2)n&(n-1):将n的二进制表示中的最低位为1的改成0(在这里注意重复操作)

231. Power of Two

Given an integer, write a function to determine if it is a power of two.

Example 1:

1
2
3
Input: 1
Output: true
Explanation: 20 = 1

Example 2:

1
2
3
Input: 16
Output: true
Explanation: 24 = 16

Example 3:

1
2
Input: 218
Output: false
1
2
3
4
5
6
7
8
9
10
11
12
13
// 2 : 10
// 4 : 100
// 8 : 1000
// 16: 10000

// n : 16 10000
// n - 1 : 01111
//如果与的结果都为0,那么就是2的次方倍
class Solution {
public boolean isPowerOfTwo(int n) {
return n > 0 && ((n & (n - 1)) == 0);
}
}

190. Reverse Bits

Reverse bits of a given 32 bits unsigned integer.

Example 1:

1
2
3
Input: 00000010100101000001111010011100
Output: 00111001011110000010100101000000
Explanation: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000.

Example 2:

1
2
3
Input: 11111111111111111111111111111101
Output: 10111111111111111111111111111111
Explanation: The input binary string 11111111111111111111111111111101 represents the unsigned integer 4294967293, so return 3221225471 which its binary representation is 10111111111111111111111111111111.

Note:

  • Note that in some languages such as Java, there is no unsigned integer type. In this case, both input and output will be given as signed integer type and should not affect your implementation, as the internal binary representation of the integer is the same whether it is signed or unsigned.
  • In Java, the compiler represents the signed integers using 2’s complement notation. Therefore, in Example 2 above the input represents the signed integer -3 and the output represents the signed integer -1073741825.

Follow up:

If this function is called many times, how would you optimize it?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 1011 右移变成0101
// 0001
// 1
// res = 1

public class Solution {
// you need treat n as an unsigned value
public int reverseBits(int n) {
if (n == 0) return 0;
int res = 0;
for (int i = 0; i < 32; i++) {
res <<= 1;
//如果是偶数,为0,并且判断最低位是不是1
if ((n & 1) == 1) res++;
// 1011 右移变成0101
n >>= 1;
}
return res;
}
}

27. Remove Element

Given an array nums and a value val, remove all instances of that value in-place and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

The order of elements can be changed. It doesn’t matter what you leave beyond the new length.

Example 1:

1
2
3
4
5
Given nums = [3,2,2,3], val = 3,

Your function should return length = 2, with the first two elements of nums being 2.

It doesn't matter what you leave beyond the returned length.

Example 2:

1
2
3
4
5
6
7
Given nums = [0,1,2,2,3,0,4,2], val = 2,

Your function should return length = 5, with the first five elements of nums containing 0, 1, 3, 0, and 4.

Note that the order of those five elements can be arbitrary.

It doesn't matter what values are set beyond the returned length.

Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

Internally you can think of this:

1
2
3
4
5
6
7
8
// nums is passed in by reference. (i.e., without making a copy)
int len = removeElement(nums, val);

// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
print(nums[i]);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//在List中是相等,在Array中是不等
//双指针法:一个从前向后扫,一个记录结果,
class Solution {
public int removeElement(int[] nums, int val) {
if (nums == null || nums.length == 0) return 0;
int res = 0;
for (int i = 0; i < nums.length; i++) {
//如果和val相等,i向前走,r不变
if(nums[i] != val) {
nums[res++] = nums[i];
}
}
return res;
}
}
// @lc code=end


// class Solution {
// public int removeElement(int[] nums, int val) {
// int ans = 0;
// for(int num: nums) {
// if(num != val) {
// nums[ans] = num;
// ans++;
// }
// }
// return ans;
// }
// }

// class Solution {
// public int removeElement(int[] nums, int val) {
// int i = 0;
// for (int j = 0; j < nums.length; ++j) {
// if (nums[j] != val) {
// nums[i] = nums[j];
// i++;
// }
// }
// return i;
// }
// }

26. Remove Duplicates from Sorted Array

Given a sorted array nums, remove the duplicates in-place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.

Example 1:

1
2
3
4
5
Given nums = [1,1,2],

Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.

It doesn't matter what you leave beyond the returned length.

Example 2:

1
2
3
4
5
Given nums = [0,0,1,1,1,2,2,3,3,4],

Your function should return length = 5, with the first five elements of nums being modified to 0, 1, 2, 3, and 4 respectively.

It doesn't matter what values are set beyond the returned length.

Clarification:

Confused why the returned value is an integer but your answer is an array?

Note that the input array is passed in by reference, which means modification to the input array will be known to the caller as well.

Internally you can think of this:

1
2
3
4
5
6
7
8
// nums is passed in by reference. (i.e., without making a copy)
int len = removeDuplicates(nums);

// any modification to nums in your function would be known by the caller.
// using the length returned by your function, it prints the first len elements.
for (int i = 0; i < len; i++) {
print(nums[i]);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Solution {
public int removeDuplicates(int[] nums) {
if (nums == null || nums.length == 0) return 0;
//第一个数一定被保持,
int count = 1;
for (int i = 1; i < nums.length; i++) {
if(nums[i - 1] != nums[i]) {
//如果相同,那么count不变,i++
nums[count++] = nums[i];
}
}
return count;
}
}



// class Solution {
// public int removeDuplicates(int[] nums) {
// if (nums == null || nums.length == 0) return 0;
// int i = 0;
// for (int j = 1; j < nums.length; ++j) {
// if (nums[j] != nums[i]) {
// i++;
// nums[i] = nums[j];
// }
// }
// return i + 1;
// }
// }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 * [80] 删除排序数组中的重复项 II
*/

// @lc code=start
class Solution {
public int removeDuplicates(int[] nums) {
if (nums.length <= 2) return nums.length;
int count = 2;
for(int i = 2; i < nums.length; i++) {
if(nums[i] != nums[count - 2]){
nums[count++] = nums[i];
}
}
return count;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 * [83] 删除排序链表中的重复元素
*/

// @lc code=start
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) return head;
ListNode cur = head;
while (cur.next != null) {
if(cur.next.val == cur.val) {
cur.next = cur.next.next;
} else {
cur = cur.next;// movre forward when do not have replcaited item;
}
}
return head;
}
}

53. Maximum Subarray

Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum and return its sum.

Example:

1
2
3
Input: [-2,1,-3,4,-1,2,1,-5,4],
Output: 6
Explanation: [4,-1,2,1] has the largest sum = 6.

Follow up:

If you have figured out the O(n) solution, try coding another solution using the divide and conquer approach, which is more subtle.

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
//dp,前N个数的和就是它的DP值
public int maxSubArray(int[] nums) {
int[] dp = new int[nums.length];
dp[0] = nums[0];
int res = nums[0];
for(int i = 1; i < nums.length; i++) {
dp[i] = nums[i] + (dp[i - 1] < 0 ? 0 : dp[i - 1]);
res = Math.max(res, dp[i]);
}
return res;
}
}

186.reverse-words-in-a-string-ii)

给定一个字符串,逐个翻转字符串中的每个单词。

示例 1:

1
2
输入: "the sky is blue"
输出: "blue is sky the"
  • 时间复杂度为O(n),因为整体遍历和单个单词遍历的的复杂度都为n,r从0走到最右的复杂度也是n,这样就是3n的复杂度,忽略指数,即可得到O(n)
  • 空间复杂度为O(1)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//先整体翻转,然后使用双指针法,将r指向单词后的空格部分,再逐一翻转单词
class Solution {
public String reverseWords(char[] s) {
reverse(s, 0, s.length - 1);
int r = 0;
while (r < s.length) {
int l = r;
while (r < s.length && s[r] != ' ') {
r++;
}
//因为r在空格上,所以要删除单词的话,就要前进一格。
reverse(s, l, r - 1);
r++;
}

}
public void reverse(char[] s, int i, int j) {
while (i < j) {
char temp = s[i];
s[i++] = s[j];
s[j--] = temp;
}
}
}

151. Reverse Words in a String

trim去掉前后空格,split 中的\\s指所有的空格回车,+指有一个或者多个

Given an input string, reverse the string word by word.

Example 1:

1
2
Input: "the sky is blue"
Output: "blue is sky the"

Example 2:

1
2
3
Input: "  hello world!  "
Output: "world! hello"
Explanation: Your reversed string should not contain leading or trailing spaces.

Example 3:

1
2
3
Input: "a good   example"
Output: "example good a"
Explanation: You need to reduce multiple spaces between two words to a single space in the reversed string.

Note:

  • A word is defined as a sequence of non-space characters.
  • Input string may contain leading or trailing spaces. However, your reversed string should not contain leading or trailing spaces.
  • You need to reduce multiple spaces between two words to a single space in the reversed string.

Follow up:

For C programmers, try to solve it in-place in O(1) extra space.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// @lc code=start
class Solution {
public String reverseWords(String s) {
if (s == null || s.length() == 0) {
return s;
}
String[] words = s.trim().split("\\s+");
StringBuilder sb = new StringBuilder();
for (int i = words.length - 1; i >= 0; i--) {
sb.append(words[i] + ' ');
}
return sb.toString().trim();
}
}
// @lc code=end
// //先整体翻转,然后使用双指针法,将r指向单词后的空格部分,再逐一翻转单词
// class Solution {
// public String reverseWords(char[] s) {
// reverse(s, 0, s.length - 1);
// int r = 0;
// while (r < s.length) {
// int l = r;
// while (r < s.length && s[r] != ' ') {
// r++;
// }
// //因为r在空格上,所以要删除单词的话,就要前进一格。
// reverse(s, l, r - 1);
// r++;
// }

// }
// public void reverse(char[] s, int i, int j) {
// while (i < j) {
// char temp = s[i];
// s[i++] = s[j];
// s[j--] = temp;
// }
// }
// }

345. Reverse Vowels of a String

Write a function that takes a string as input and reverse only the vowels of a string.

Example 1:

1
2
Input: "hello"
Output: "holle"

Example 2:

1
2
Input: "leetcode"
Output: "leotcede"

Note:
The vowels does not include the letter “y”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public String reverseVowels(String s) {
if (s == null || s.length() == 0) return s;
String vowel = "aeiouAEIOU";
char[] str = s.toCharArray();
int left = 0;
int right = s.length() - 1;
while (left < right) {
//如果找不到,就前进
while (left < right && vowel.indexOf(str[left]) == -1) {
left++;
}
while (left < right && vowel.indexOf(str[right]) == -1) {
right--;
}
char temp = str[left];
str[left++] = str[right];
str[right--] = temp;
}
return new String(str);
}
}

13.Roman to Integer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// 首先将所有的组合可能性列出并添加到哈希表中
// 然后对字符串进行遍历,由于组合只有两种,一种是 1 个字符,一种是 2 个字符,其中 2 个字符优先于 1 个字符
// 先判断两个字符的组合在哈希表中是否存在,存在则将值取出加到结果 ans 中,并向后移2个字符。不存在则将判断当前 1 个字符是否存在,存在则将值取出加到结果 ans 中,并向后移 1 个字符
// 遍历结束返回结果 ans
class Solution {
public int romanToInt(String s) {
Map<String, Integer> map = new HashMap<>();
map.put("I", 1);
map.put("IV", 4);
map.put("V", 5);
map.put("IX", 9);
map.put("X", 10);
map.put("XL", 40);
map.put("L", 50);
map.put("XC", 90);
map.put("C", 100);
map.put("CD", 400);
map.put("D", 500);
map.put("CM", 900);
map.put("M", 1000);
int ans = 0;
for(int i = 0;i < s.length();) {
if (i + 1 < s.length() && map.containsKey(s.substring(i, i+2))) {
ans += map.get(s.substring(i, i+2));
i += 2;
} else {
ans += map.get(s.substring(i, i+1));
i++;
}
}
return ans;
}

12. Integer to Roman

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public String intToRoman(int num) {
int[] values = {1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1};
String[] strs = {"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
StringBuilder sb = new StringBuilder();
for(int i = 0; i < values.length; i++) {
while (num >= values[i]) {
num -= values[i];
sb.append(strs[i]);
}
}
return sb.toString();
}
}

273. Integer to English Words

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Solution {
String[] less20 = {"", "One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten", "Eleven", "Twelve", "Thirteen", "Fourteen", "Fifteen", "Sixteen", "Seventeen", "Eighteen", "Nineteen"};
String[] tens = {"", "Ten", "Twenty", "Thirty", "Forty", "Fifty", "Sixty", "Seventy", "Eighty", "Ninety"};
String[] thousands = {"", "Thousand", "Million", "Billion"};
public String numberToWords(int num) {
if (num == 0) return "Zero";
String res = "";
int i = 0;
while (num > 0) {
if (num % 1000 != 0) {
res = helper(num % 1000)+ thousands[i] + " " + res;
}
num /= 1000;
i++;
}
return res.trim();
}
public String helper(int num) {
if (num == 0) return "";
if (num < 20) {
return less20[num % 20] + " ";
} else if (num < 100) {
return tens[num / 10] + " " + helper(num % 10);
} else {
return less20[num / 100] + " Hundred " + helper(num % 100);
}
}
}

1.Two Sum

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly\ one solution, and you may not use the same element twice.

Example:

1
2
3
4
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
int complement = target - nums[i];
if(map.containsKey(complement)) {
return new int[] {map.get(complement), i};
}
map.put(nums[i], i);
}
throw new IllegalArgumentException("No two sum solution");
}
}
// for (int i = 0; i < nums.length; ++i) {
// for (int j = i + 1; j < nums.length; ++j) {
// if (nums[j] == target - nums[i]) {
// return new int[] {i, j};
// }
// }
// }
// throw new IllegalArgumentException("No solution");

15.Three Sum

Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.

Note:

The solution set must not contain duplicate triplets.

Example:

1
2
3
4
5
6
7
Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
[-1, 0, 1],
[-1, -1, 2]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Solution {
public List<List<Integer>> threeSum(int[] nums) {
List<List<Integer>> ans = new ArrayList();
int len = nums.length;
if (nums == null || len < 3) return ans;
Arrays.sort(nums);// 排序
for (int i = 0; i < len; i++) {
if(nums[i] > 0) break;// 如果当前数字大于0,则三数之和一定大于0,所以结束循环
if (i > 0 && nums[i] == nums[i-1]) continue;// 去重
int L = i + 1;
int R = len - 1;
while (L < R) {
int sum = nums[i] + nums[L] + nums[R];
if(sum == 0) {
ans.add(Arrays.asList(nums[i], nums[L], nums[R]));
while (L < R && nums[L] == nums[L+1]) L++;// 去重
while (L < R && nums[R] == nums[R-1]) R--;// 去重
L++;
R--;
}
else if (sum < 0) L++;
else if (sum > 0) R--;
}
}
return ans;
}
}

16. 3Sum Closest

Given an array nums of n integers and an integer target, find three integers in nums such that the sum is closest to target. Return the sum of the three integers. You may assume that each input would have exactly one solution.

Example 1:

1
2
3
Input: nums = [-1,2,1,-4], target = 1
Output: 2
Explanation: The sum that is closest to the target is 2. (-1 + 2 + 1 = 2).

Constraints:

  • 3 <= nums.length <= 10^3

  • -10^3 <= nums[i] <= 10^3

  • -10^4 <= target <= 10^4

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    // @lc code=start
    //只有在从小到大排序后,才能移动left和right(因为排序是为了去重)
    class Solution {
    public int threeSumClosest(int[] nums, int target) {
    int res = nums[0] + nums[1] + nums[nums.length - 1];
    Arrays.sort(nums);
    for(int i = 0; i < nums.length - 2; i++) {
    int start = i + 1, end = nums.length - 1;
    while (start < end) {
    int sum = nums[i] + nums[start] + nums[end];
    if (sum > target) {
    end--;
    } else {
    start++;
    }
    if(Math.abs(sum - target) < Math.abs(res - target)) {
    //绝对值偏小,说明更接近
    res = sum;
    }
    }
    }
    return res;
    }
    }

18. 4 Sum

Given an array nums of n integers and an integer target, are there elements a, b, c, and d in nums such that a + b + c + d = target? Find all unique quadruplets in the array which gives the sum of target.

Note:

The solution set must not contain duplicate quadruplets.

Example:

1
2
3
4
5
6
7
8
Given array nums = [1, 0, -1, 0, -2, 2], and target = 0.

A solution set is:
[
[-1, 0, 0, 1],
[-2, -1, 1, 2],
[-2, 0, 0, 2]
]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
class Solution {
public List<List<Integer>> fourSum(int[] nums,int target){
/*定义一个返回值*/
List<List<Integer>> result=new ArrayList<>();
/*当数组为null或元素小于4个时,直接返回*/
if(nums==null||nums.length<4){
return result;
}
/*对数组进行从小到大排序*/
Arrays.sort(nums);
/*数组长度*/
int length=nums.length;
/*定义4个指针k,i,j,h k从0开始遍历,i从k+1开始遍历,留下j和h,j指向i+1,h指向数组最大值*/
for(int k=0;k<length-3;k++){
/*当k的值与前面的值相等时忽略*/
if(k>0&&nums[k]==nums[k-1]){
continue;
}
/*获取当前最小值,如果最小值比目标值大,说明后面越来越大的值根本没戏*/
int min1=nums[k]+nums[k+1]+nums[k+2]+nums[k+3];
if(min1>target){
break;
}
/*获取当前最大值,如果最大值比目标值小,说明后面越来越小的值根本没戏,忽略*/
int max1=nums[k]+nums[length-1]+nums[length-2]+nums[length-3];
if(max1<target){
continue;
}
/*第二层循环i,初始值指向k+1*/
for(int i=k+1;i<length-2;i++){
/*当i的值与前面的值相等时忽略*/
if(i>k+1&&nums[i]==nums[i-1]){
continue;
}
/*定义指针j指向i+1*/
int j=i+1;
/*定义指针h指向数组末尾*/
int h=length-1;
/*获取当前最小值,如果最小值比目标值大,说明后面越来越大的值根本没戏,忽略*/
int min=nums[k]+nums[i]+nums[j]+nums[j+1];
if(min>target){
continue;
}
/*获取当前最大值,如果最大值比目标值小,说明后面越来越小的值根本没戏,忽略*/
int max=nums[k]+nums[i]+nums[h]+nums[h-1];
if(max<target){
continue;
}
/*开始j指针和h指针的表演,计算当前和,如果等于目标值,j++并去重,h--并去重,当当前和大于目标值时h--,当当前和小于目标值时j++*/
while (j<h){
int curr=nums[k]+nums[i]+nums[j]+nums[h];
if(curr==target){
result.add(Arrays.asList(nums[k],nums[i],nums[j],nums[h]));
j++;
while(j<h&&nums[j]==nums[j-1]){
j++;
}
h--;
while(j<h&&i<h&&nums[h]==nums[h+1]){
h--;
}
}else if(curr>target){
h--;
}else {
j++;
}
}
}
}
return result;
}
}

242. Valid Anagram

Given two strings s and t , write a function to determine if t is an anagram of s.

Example 1:

1
2
Input: s = "anagram", t = "nagaram"
Output: true

Example 2:

1
2
Input: s = "rat", t = "car"
Output: false

Note:
You may assume the string contains only lowercase alphabets.

Follow up:
What if the inputs contain unicode characters? How would you adapt your solution to such case?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public boolean isAnagram(String s, String t) {
if (s.length() != t.length()) {
return false;
}
int[] count = new int[26];
for(int i = 0; i < s.length(); i++) {
count[s.charAt(i) - 'a']++;
count[t.charAt(i) - 'a']--;
}
for (int num : count) {
if (num != 0) return false;
}
return true;
}
}

49. Group Anagrams

Given an array of strings, group anagrams together.

Example:

1
2
3
4
5
6
7
Input: ["eat", "tea", "tan", "ate", "nat", "bat"],
Output:
[
["ate","eat","tea"],
["nat","tan"],
["bat"]
]

Note:

  • All inputs will be in lowercase.
  • The order of your output does not matter.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
import java.util.HashMap;
import java.util.List;
import java.util.*;

/*
* @lc app=leetcode.cn id=49 lang=java
*
* [49] 字母异位词分组
*/

// @lc code=start
//time:O(m + n) m:strs长度 n:strs中最大String的长度
//space: O(n)级别
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
//counting为key, 字符串为value
//讲aabbc和ababc存入a2b2c1
HashMap<String, List<String>> map = new HashMap<>();
for(String str : strs) {
//对当前的单个单词进行counting sort
int[] count = new int[26];
for(Character ch : str.toCharArray()) {
count[ch - 'a']++;
}
//设置基准
String s = "";
for(int i = 0; i < count.length; i++) {
//等于0,说明字母没有出现,在这里只数出现过的字母
if(count[i] != 0) {
//valueOf将字母出现的次数从Int型转换成String类型
s += String.valueOf(count[i]) + String.valueOf((char)(i + 'a'));
//之前减去a,现在加上a,就恢复到了a
}
}
if (map.containsKey(s)) {
//如果已经包含了,就取出来,然后加进去
List<String> list = map.get(s);
list.add(str);
} else {
//如果第一次出现
List<String> list = new ArrayList<>();//初始化List
list.add(str);//将2a2b1c和aabbc加入到list中
map.put(s, list);
}
}
return new ArrayList<>(map.values());
}
}
// @lc code=end

14. Longest Common Prefix

Write a function to find the longest common prefix string amongst an array of strings.

If there is no common prefix, return an empty string "".

Example 1:

1
2
Input: ["flower","flow","flight"]
Output: "fl"

Example 2:

1
2
3
Input: ["dog","racecar","car"]
Output: ""
Explanation: There is no common prefix among the input strings.

Note:

All given inputs are in lowercase letters a-z.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
* @lc app=leetcode.cn id=14 lang=java
*
* [14] 最长公共前缀
*/

// @lc code=start
class Solution {
public String longestCommonPrefix(String[] strs) {
if(strs.length == 0) {
return "";
}
String ans = strs[0];
for(int i = 1; i < strs.length; i++) {
int j = 0;
for(;j < ans.length() && j < strs[i].length();j++) {
if(ans.charAt(j) != strs[i].charAt(j))
break;
}
ans = ans.substring(0, j);
if(ans.equals(""))
return ans;
}
return ans;

}
}

74. Search a 2D Matrix

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

  • Integers in each row are sorted from left to right.
  • The first integer of each row is greater than the last integer of the previous row.

Example 1:

1
2
3
4
5
6
7
8
Input:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 3
Output: true

Example 2:

1
2
3
4
5
6
7
8
Input:
matrix = [
[1, 3, 5, 7],
[10, 11, 16, 20],
[23, 30, 34, 50]
]
target = 13
Output: false
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix.length == 0 || matrix[0].length == 0) return false;
int row = matrix.length;
int col = matrix[0].length;
int start = 0;
int end = row * col - 1;

while (start <= end) {
int mid = start + (end - start) / 2;
int value = matrix[mid / col][mid % col];
if (value == target) {
return true;
} else if (value < target) {
start = mid + 1;
} else {
end = mid - 1;
}
}
return false;
}
}

240.Search a 2D Matrix II

Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the following properties:

  • Integers in each row are sorted in ascending from left to right.
  • Integers in each column are sorted in ascending from top to bottom.

Example:

Consider the following matrix:

1
2
3
4
5
6
7
[
[1, 4, 7, 11, 15],
[2, 5, 8, 12, 19],
[3, 6, 9, 16, 22],
[10, 13, 14, 17, 24],
[18, 21, 23, 26, 30]
]

Given target = 5, return true.

Given target = 20, return false.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public boolean searchMatrix(int[][] matrix, int target) {
if (matrix.length == 0 || matrix[0].length == 0) return false;
int row = 0;
int col = matrix[0].length - 1;
while (col >= 0 && row <= matrix.length - 1) {
if (target == matrix[row][col]) {
return true;
} else if (target < matrix[row][col]) {
col--;
} else {
row++;
}
}
return false;
}
}

35. Search Insert Position

Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order.

You may assume no duplicates in the array.

Example 1:

1
2
Input: [1,3,5,6], 5
Output: 2

Example 2:

1
2
Input: [1,3,5,6], 2
Output: 1

Example 3:

1
2
Input: [1,3,5,6], 7
Output: 4

Example 4:

1
2
Input: [1,3,5,6], 0
Output: 0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// 首先,插入位置有可能在数组的末尾(题目中的示例 3),需要单独判断;
// 其次,如果待插入元素比最后一个元素严格小,并且在这个数组中有和插入元素一样的元素,返回任意一个位置即可;
// 否则,插入的位置应该是严格大于 target 的第 1 个元素的位置。
//因此,严格小于 target 的元素一定不是解,根据这个思路,可以写出如下代码。

class Solution {
public int searchInsert(int[] nums, int target) {
int len = nums.length;
if (len == 0) {
return 0;
}
if (nums[len - 1] < target) {
return len;
}
int left = 0;
int right = len - 1;
while (left < right) {
int mid = (left + right) >>> 1;
// 严格小于 target 的元素一定不是解
if (nums[mid] < target) {
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
}

[374. Guess Number Higher or Lower]https://leetcode.com/problems/guess-number-higher-or-lower/

We are playing the Guess Game. The game is as follows:

I pick a number from 1 to n\. You have to guess which number I picked.

Every time you guess wrong, I’ll tell you whether the number is higher or lower.

You call a pre-defined API guess(int num) which returns 3 possible results (-1, 1, or 0):

1
2
3
-1 : My number is lower
1 : My number is higher
0 : Congrats! You got it!

Example :

1
2
Input: n = 10, pick = 6
Output: 6
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class Solution extends GuessGame {
public int guessNumber(int n) {
int left = 1;
int right = n;
while (left < right) {
int mid = (left + right + 1) >>> 1;
int guessNum = guess(mid);
if (guessNum == -1) {
right = mid - 1;// 中位数比猜的数大,因此比中位数大的数包括中位数都不是目标元素
} else {
left = mid;
}
}
return left;
}
}

278. First Bad Version

You are a product manager and currently leading a team to develop a new product. Unfortunately, the latest version of your product fails the quality check. Since each version is developed based on the previous version, all the versions after a bad version are also bad.

Suppose you have n versions [1, 2, ..., n] and you want to find out the first bad one, which causes all the following ones to be bad.

You are given an API bool isBadVersion(version) which will return whether version is bad. Implement a function to find the first bad version. You should minimize the number of calls to the API.

Example:

1
2
3
4
5
6
7
Given n = 5, and version = 4 is the first bad version.

call isBadVersion(3) -> false
call isBadVersion(5) -> true
call isBadVersion(4) -> true

Then 4 is the first bad version.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
/* The isBadVersion API is defined in the parent class VersionControl.
boolean isBadVersion(int version); */

public class Solution extends VersionControl {
public int firstBadVersion(int n) {
int left = 1;
int right = n;
while (left < right) {
int mid = left + (right - left) / 2;
if(isBadVersion(mid)) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
}

34. Find First and Last Position of Element in Sorted Array

Given an array of integers nums sorted in ascending order, find the starting and ending position of a given target value.

Your algorithm’s runtime complexity must be in the order of O(log n).

If the target is not found in the array, return [-1, -1].

Example 1:

1
2
Input: nums = [5,7,7,8,8,10], target = 8
Output: [3,4]

Example 2:

1
2
Input: nums = [5,7,7,8,8,10], target = 6
Output: [-1,-1]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
class Solution {
public int[] searchRange(int[] nums, int target) {
if (nums == null || nums.length ==0) return new int[]{-1, -1};
int start = findFirst(nums, target);
if(start == -1) return new int[]{-1, -1};
int end = findLast(nums, target);
return new int[]{start, end};
}
public int findFirst(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if(nums[mid] < target) {
start = mid;
} else {
end = mid;
}
}
if(nums[start] == target) return start;
if(nums[end] == target) return end;
return -1;
}
public int findLast(int[] nums, int target) {
int start = 0;
int end = nums.length - 1;
while (start + 1 < end) {
int mid = start + (end - start) / 2;
if(nums[mid] > target) {
end = mid;
} else {
start = mid;
}
}
if(nums[end] == target) return end;
if(nums[start] == target) return start;
return -1;
}
}

162.Find Peak Element

A peak element is an element that is greater than its neighbors.

Given an input array nums, where nums[i] ≠ nums[i+1], find a peak element and return its index.

The array may contain multiple peaks, in that case return the index to any one of the peaks is fine.

You may imagine that nums[-1] = nums[n] = -∞.

Example 1:

1
2
3
Input: nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.

Example 2:

1
2
3
4
Input: nums = [1,2,1,3,5,6,4]
Output: 1 or 5
Explanation: Your function can return either index number 1 where the peak element is 2,
or index number 5 where the peak element is 6.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public int findPeakElement(int[] nums) {
int start = 0;
int end = nums.length - 1;
while (start <= end) {
if (start == end) return start;
int mid = start + (end - start) / 2;
if(nums[mid] >= nums[mid + 1]) {
end = mid;
} else {
start = mid + 1;
}
}
return start;
}
}

141. Linked List Cycle

Given a linked list, determine if it has a cycle in it.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Example 1:

1
2
3
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the second node.

img

Example 2:

1
2
3
Input: head = [1,2], pos = 0
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the first node.

img

Example 3:

1
2
3
Input: head = [1], pos = -1
Output: false
Explanation: There is no cycle in the linked list.

img

Follow up:

Can you solve it using O(1) (i.e. constant) memory?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class Solution {
public boolean hasCycle(ListNode head) {
if(head == null || head.next == null) return false;
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (slow == fast) {
return true;
}
}
return false;
}
}

142. Linked List Cycle II

Given a linked list, return the node where the cycle begins. If there is no cycle, return null.

To represent a cycle in the given linked list, we use an integer pos which represents the position (0-indexed) in the linked list where tail connects to. If pos is -1, then there is no cycle in the linked list.

Note: Do not modify the linked list.

Example 1:

1
2
3
Input: head = [3,2,0,-4], pos = 1
Output: tail connects to node index 1
Explanation: There is a cycle in the linked list, where tail connects to the second node.

img

Example 2:

1
2
3
Input: head = [1,2], pos = 0
Output: tail connects to node index 0
Explanation: There is a cycle in the linked list, where tail connects to the first node.

img

Example 3:

1
2
3
Input: head = [1], pos = -1
Output: no cycle
Explanation: There is no cycle in the linked list.

img

Follow-up:
Can you solve it without using extra space?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class Solution {
public ListNode detectCycle(ListNode head) {
if (head == null || head.next == null) return null;
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
if (fast == slow) {
ListNode slow2 = head;
while(slow != slow2) {
slow = slow.next;
slow2 = slow2.next;
}
return slow;
}
}
return null;
}
}

83. Remove Duplicates from Sorted List

Given a sorted linked list, delete all duplicates such that each element appear only once.

Example 1:

1
2
Input: 1->1->2
Output: 1->2

Example 2:

1
2
Input: 1->1->2->3->3
Output: 1->2->3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null || head.next == null) return head;
ListNode cur = head;
while (cur.next != null) {
if(cur.next.val == cur.val) {
cur.next = cur.next.next;
} else {
cur = cur.next;// movre forward when do not have replcaited item;
}
}
return head;
}
}

82. Remove Duplicates from Sorted List II

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

Return the linked list sorted as well.

Example 1:

1
2
Input: 1->2->3->3->4->4->5
Output: 1->2->5

Example 2:

1
2
Input: 1->1->1->2->3
Output: 2->3
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if(head == null || head.next == null) return head;
ListNode dummy = new ListNode(0);
//删除当前节点的方法是在将要删除的节点前面再加一个dummy节点,这样才能指向dummy.next.next,也就是删除dummy.next。
dummy.next = head;//这样才能删除头指针节点
ListNode p = dummy;
while (p.next != null && p.next.next != null) {
if(p.next.val == p.next.next.val) {
//用来删除全部的重复节点,保存一下重复值
int sameNum = p.next.val;
while (p.next != null && p.next.val == sameNum) {
p.next = p.next.next;
}
} else {
p = p.next;
}
}
return dummy.next;
}
}