1 基础知识
面试题3:数组中重复的数字
https://leetcode.cn/problems/shu-zu-zhong-zhong-fu-de-shu-zi-lcof/
class Solution {
public int findRepeatNumber(int[] nums) {
Arrays.sort(nums);
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] == nums[i + 1]) {
return nums[i];
}
}
return Integer.MAX_VALUE;
}
}
面试题4:二维数组中的查找
https://leetcode.cn/problems/er-wei-shu-zu-zhong-de-cha-zhao-lcof/
class Solution {
public boolean findNumberIn2DArray(int[][] matrix, int target) {
if (matrix.length < 1 || matrix[0].length < 1) {
return false;
}
int i = 0;
int j = matrix[i].length - 1;
while (i < matrix.length && j >= 0) {
if (matrix[i][j] == target) {
return true;
} else if (matrix[i][j] > target) {
j--;
} else {
i++;
}
}
return false;
}
}
面试官5:替换空格
https://leetcode.cn/problems/ti-huan-kong-ge-lcof/
class Solution {
public String replaceSpace(String s) {
char[] cArray = s.toCharArray();
StringBuilder sb = new StringBuilder();
for (int i = 0; i < cArray.length; i++) {
sb.append(Character.isSpaceChar(cArray[i]) ? "%20" : cArray[i]);
}
return sb.toString();
}
}
面试题6:从尾到头打印链表
https://leetcode.cn/problems/cong-wei-dao-tou-da-yin-lian-biao-lcof/
class Solution {
List<Integer> list = new ArrayList<>();
public int[] reversePrint(ListNode head) {
if (head == null) {
return new int[0];
}
reverse(head);
int[] array = new int[list.size()];
for (int i = 0; i < array.length; i++) {
array[i] = list.get(i);
}
return array;
}
public void reverse(ListNode head) {
if (head.next != null) {
reversePrint(head.next);
}
list.add(head.val);
}
}
面试题9:用两个栈实现队列
https://leetcode.cn/problems/yong-liang-ge-zhan-shi-xian-dui-lie-lcof/
class CQueue {
Stack<Integer> stack1;
Stack<Integer> stack2;
public CQueue() {
stack1 = new Stack();
stack2 = new Stack();
}
public void appendTail(int value) {
stack2.push(value);
}
public int deleteHead() {
int head = -1;
if (stack1.size() > 0 || stack2.size() > 0) {
if (stack1.size() == 0 && stack2.size() > 0) {
while (stack2.size() > 0) {
stack1.push(stack2.pop());
}
}
head = stack1.pop();
}
return head;
}
}
面试题10-1:斐波那契数列
https://leetcode.cn/problems/fei-bo-na-qi-shu-lie-lcof/
class Solution {
public int fib(int n) {
int x = 0;
int y = 1;
int z = 1;
while (n > 0) {
z = (x + y) % 1000000007;
x = y;
y = z;
n--;
}
return x;
}
}
面试题10-2:青蛙跳台阶问题
https://leetcode.cn/problems/qing-wa-tiao-tai-jie-wen-ti-lcof/
class Solution {
Map<Integer, Integer> map = new HashMap();
public int numWays(int n) {
if (n == 1) {
return 1;
}
if (n == 2) {
return 2;
}
if (n > 2) {
if (map.containsKey(n)) {
return map.get(n);
}
int num = (numWays(n - 1) + numWays(n - 2)) % 1000000007;
map.put(n, num);
return num;
}
return 1;
}
}
面试题11:旋转数组的最小数字
https://leetcode.cn/problems/xuan-zhuan-shu-zu-de-zui-xiao-shu-zi-lcof/
class Solution {
public int minArray(int[] numbers) {
if (numbers.length == 0) {
return Integer.MAX_VALUE;
}
int result = numbers[0];
for (int i = 0; i < numbers.length - 1; i++) {
if (numbers[i] > numbers[i + 1]) {
return numbers[i + 1];
}
}
return result;
}
}
面试题12:矩阵中的路径
https://leetcode.cn/problems/ju-zhen-zhong-de-lu-jing-lcof/
class Solution {
public boolean exist(char[][] board, String word) {
if ("".equals(word)) {
return true;
}
if (board.length == 0 || board[0].length == 0) {
return false;
}
boolean[][] passed = new boolean[board.length][board[0].length];
char[] cArray = word.toCharArray();
List<String> starts = new ArrayList();
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == cArray[0]) {
starts.add(i + "," + j);
}
}
}
if (!starts.isEmpty()) {
for (int k = 0; k < starts.size(); k++) {
String[] strs = starts.get(k).split(",");
int x = Integer.parseInt(strs[0]);
int y = Integer.parseInt(strs[1]);
passed[x][y] = true;
if (next(board, cArray, x, y, 1, passed)) {
return true;
}
passed[x][y] = false;
}
}
return false;
}
public boolean next(char[][] board, char[] cArray, int x, int y, int next, boolean[][] passed) {
if (next == cArray.length) {
return true;
}
boolean bool;
if (x > 0 && board[x - 1][y] == cArray[next] && !passed[x - 1][y]) {
passed[x - 1][y] = true;
bool = next(board, cArray, x - 1, y, next + 1, passed);
passed[x - 1][y] = false;
if (bool) {
return true;
}
}
if (y > 0 && board[x][y - 1] == cArray[next] && !passed[x][y - 1]) {
passed[x][y - 1] = true;
bool = next(board, cArray, x, y - 1, next + 1, passed);
passed[x][y - 1] = false;
if (bool) {
return true;
}
}
if (x < board.length - 1 && board[x + 1][y] == cArray[next] && !passed[x + 1][y]) {
passed[x + 1][y] = true;
bool = next(board, cArray, x + 1, y, next + 1, passed);
passed[x + 1][y] = false;
if (bool) {
return true;
}
}
if (y < board[0].length - 1 && board[x][y + 1] == cArray[next] && !passed[x][y + 1]) {
passed[x][y + 1] = true;
bool = next(board, cArray, x, y + 1, next + 1, passed);
passed[x][y + 1] = false;
if (bool) {
return true;
}
}
return false;
}
}
面试题13:机器人的运动范围
https://leetcode.cn/problems/ji-qi-ren-de-yun-dong-fan-wei-lcof/
class Solution {
int count;
public int movingCount(int m, int n, int k) {
count = 0;
boolean[][] booleans = new boolean[m][n];
analyze(m, n, 0, 0, k, booleans);
return count;
}
public void analyze(int m, int n, int i, int j, int k, boolean[][] booleans) {
if (getCompareResult(i) + getCompareResult(j) <= k && !booleans[i][j]) {
booleans[i][j] = true;
count++;
}
if (i > 0 && getCompareResult(i - 1) + getCompareResult(j) <= k && !booleans[i - 1][j]) {
analyze(m, n, i - 1, j, k, booleans);
}
if (j > 0 && getCompareResult(i) + getCompareResult(j - 1) <= k && !booleans[i][j - 1]) {
analyze(m, n, i, j - 1, k, booleans);
}
if (i < m - 1 && getCompareResult(i + 1) + getCompareResult(j) <= k
&& !booleans[i + 1][j]) {
analyze(m, n, i + 1, j, k, booleans);
}
if (j < n - 1 && getCompareResult(i) + getCompareResult(j + 1) <= k
&& !booleans[i][j + 1]) {
analyze(m, n, i, j + 1, k, booleans);
}
}
public int getCompareResult(int num) {
int sum = 0;
while (num != 0) {
sum = sum + num % 10;
num = num / 10;
}
return sum;
}
}
面试题14-1:剪绳子
https://leetcode.cn/problems/jian-sheng-zi-lcof/
class Solution {
public int cuttingRope(int n) {
// 由题意,m>=2
int max = Integer.MIN_VALUE;
int mMax;
int base;
int rest;
for (int m = 2; m <= n; m++) {
base = n / m;
rest = n % m;
// m个数,rest个base+1,m-rest个base
mMax = (int) (Math.pow(base, m - rest) * Math.pow(base + 1, rest));
if (mMax > max) {
max = mMax;
}
}
return max;
}
}
面试题15:二进制中1的个数
https://leetcode.cn/problems/er-jin-zhi-zhong-1de-ge-shu-lcof/
class Solution {
public int hammingWeight(int n) {
int count = 0;
for (int i = 0; i < 32; i++) {
if ((n & (1 << i)) != 0) {
count++;
}
}
return count;
}
}
2 代码质量
面试题16:数值的整数次方
https://leetcode.cn/problems/shu-zhi-de-zheng-shu-ci-fang-lcof/
class Solution {
Map<Long, Double> map = new HashMap<>();
public double myPow(double x, int n) {
if (x == 0 && n < 0) {
return 0;
}
long lnl;
if (n != Integer.MIN_VALUE) {
lnl = n > 0 ? n : -n;
} else {
lnl = 2147483648L;
}
double result = getResult(x, lnl);
if (n > 0) {
return result;
} else {
return 1.0 / result;
}
}
public double getResult(double x, long n) {
if (n == 0) {
return 1;
}
if (n == 1) {
return x;
}
if (map.containsKey(n)) {
return map.get(n);
}
if (n % 2 == 0) {
map.put(n, getResult(x, n / 2) * getResult(x, n / 2));
} else {
map.put(n, getResult(x, n / 2) * getResult(x, n / 2) * x);
}
return map.get(n);
}
}
面试题17:打印从1到最大的n位数
https://leetcode.cn/problems/da-yin-cong-1dao-zui-da-de-nwei-shu-lcof/
class Solution {
public int[] printNumbers(int n) {
int count = (int) (Math.pow(10, n) - 1);
int[] result = new int[count];
for (int i = 0; i < count; i++) {
result[i] = i + 1;
}
return result;
}
}
面试题18:删除链表的节点
https://leetcode.cn/problems/shan-chu-lian-biao-de-jie-dian-lcof/
class Solution {
public ListNode deleteNode(ListNode head, int val) {
if (head == null) {
return null;
}
if (head.next == null) {
if (head.val == val) {
return null;
} else {
return head;
}
}
ListNode p1 = new ListNode(0);
p1.next = head;
ListNode p2 = head.next != null ? head.next : null;
ListNode p3 = p1;
while (p2 != null) {
if (head.val == val) {
p1.next = p2;
break;
}
p2 = p2.next != null ? p2.next : null;
head = head.next;
p1 = p1.next;
}
if (head.val == val) {
p1.next = p2;
}
return p3.next != null ? p3.next : null;
}
}
面试题20:表示数值的字符串
https://leetcode.cn/problems/biao-shi-shu-zhi-de-zi-fu-chuan-lcof/
class Solution {
static List<Character> list;
static {
list = new ArrayList();
list.add('0');
list.add('1');
list.add('2');
list.add('3');
list.add('4');
list.add('5');
list.add('6');
list.add('7');
list.add('8');
list.add('9');
}
public boolean isNumber(String s) {
String trimS = s.trim();
String upTrimS = trimS.toUpperCase();
if ("".equals(upTrimS)) {
return false;
}
char[] charS = upTrimS.toCharArray();
boolean containsE = false;
for (int i = 0; i < charS.length; i++) {
if (charS[i] == 'e' || charS[i] == 'E') {
containsE = true;
break;
}
}
if (containsE) {
if (charS[0] == 'E' || charS[charS.length - 1] == 'E') {
return false;
}
String[] byE = upTrimS.split("E");
if (byE.length != 2) {
return false;
}
char[] spilt1 = byE[0].toCharArray();
char[] spilt2 = byE[1].toCharArray();
if (spilt1.length == 0) {
return false;
}
if (!isIntNumber(spilt2)) {
return false;
}
charS = spilt1;
}
int countPoint = 0;
boolean containsNum = false;
for (int k = 0; k < charS.length; k++) {
if (k == 0 && (charS[k] == '+' || charS[k] == '-')) {
continue;
}
if (charS[k] == '.') {
countPoint++;
continue;
}
if (!list.contains(charS[k])) {
return false;
} else {
containsNum = true;
}
}
if (!containsNum || countPoint > 1) {
return false;
}
return true;
}
public boolean isIntNumber(char[] array) {
for (int j = 0; j < array.length; j++) {
if (j == 0 && (array[j] == '+' || array[j] == '-')) {
if (array.length == 1) {
return false;
}
continue;
}
if (!list.contains(array[j])) {
return false;
}
}
return true;
}
}
面试题21:调整数组顺序使奇数位于偶数前面
https://leetcode.cn/problems/diao-zheng-shu-zu-shun-xu-shi-qi-shu-wei-yu-ou-shu-qian-mian-lcof/
class Solution {
int mark;
public int[] exchange(int[] nums) {
if (nums.length < 2) {
return nums;
}
int p1 = 0;
int p2 = nums.length - 1;
while (p1 < p2) {
if (nums[p1] % 2 == 1) {
p1++;
continue;
}
if (nums[p2] % 2 == 0) {
p2--;
continue;
}
mark = nums[p1];
nums[p1] = nums[p2];
nums[p2] = mark;
p1++;
p2--;
}
return nums;
}
}
面试题22:链表中倒数第k个节点
https://leetcode.cn/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/
class Solution {
int count = Integer.MIN_VALUE;
ListNode Kth;
public ListNode getKthFromEnd(ListNode head, int k) {
if (head == null) {
return null;
}
getKth(head, k);
return Kth;
}
public void getKth(ListNode head, int k) {
if (head.next == null) {
count = 1;
} else {
getKth(head.next, k);
count++;
}
if (count == k) {
Kth = head;
}
}
}
面试题24:反转链表
https://leetcode.cn/problems/fan-zhuan-lian-biao-lcof/
class Solution {
ListNode p1;
ListNode p2;
public ListNode reverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
while (head.next != null) {
p2 = head.next;
head.next = p1;
p1 = head;
head = p2;
}
head.next = p1;
return head;
}
}
面试题25:合并两个排序的链表
https://leetcode.cn/problems/he-bing-liang-ge-pai-xu-de-lian-biao-lcof/
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
ListNode stone = new ListNode(0);
ListNode current = stone;
while (l1 != null || l2 != null) {
if (l1.val <= l2.val) {
current.next = l1;
l1 = l1.next != null ? l1.next : new ListNode(Integer.MAX_VALUE);
} else {
current.next = l2;
l2 = l2.next != null ? l2.next : new ListNode(Integer.MAX_VALUE);
}
current = current.next;
if (l1.val == Integer.MAX_VALUE && l2.val == Integer.MAX_VALUE) {
break;
}
}
return stone.next;
}
}
面试题26:树的子结构
https://leetcode.cn/problems/shu-de-zi-jie-gou-lcof/
class Solution {
boolean is = false;
public boolean isSubStructure(TreeNode A, TreeNode B) {
if (B == null) {
return is;
}
dfs(A, B, B.val);
return is;
}
public void dfs(TreeNode node1, TreeNode node2, int root) {
if (node1 == null) {
return;
}
if (!is){
if (node1.val == root) {
is = compare(node1, node2);
}
dfs(node1.left, node2, root);
dfs(node1.right, node2, root);
}
}
public boolean compare(TreeNode node1, TreeNode node2) {
if (node1 == null) {
return false;
}
if (node1.val != node2.val) {
return false;
}
boolean b1 = true;
boolean b2 = true;
if (node2.left != null) {
b1 = compare(node1.left, node2.left);
}
if (node2.right != null) {
b2 = compare(node1.right, node2.right);
}
return b1 && b2;
}
}
3 解题思路
面试题27:二叉树的镜像
https://leetcode.cn/problems/er-cha-shu-de-jing-xiang-lcof/
class Solution {
TreeNode treeNode;
public TreeNode mirrorTree(TreeNode root) {
if (root == null) {
return null;
}
mirror(root);
return root;
}
public void mirror(TreeNode node) {
treeNode = node.left;
node.left = node.right;
node.right = treeNode;
if (node.left != null) {
mirror(node.left);
}
if (node.right != null) {
mirror(node.right);
}
}
}
面试题28:对称的二叉树
https://leetcode.cn/problems/dui-cheng-de-er-cha-shu-lcof/
class Solution {
public boolean isSymmetric(TreeNode root) {
if (root == null) {
return true;
}
return compare(root.left, root.right);
}
public boolean compare(TreeNode node1, TreeNode node2) {
if (node1 == null && node2 == null) {
return true;
}
if (node1 == null || node2 == null) {
return false;
}
if (node1.val != node2.val) {
return false;
}
return compare(node1.left, node2.right) && compare(node1.right, node2.left);
}
}
面试题29:顺时针打印矩阵
https://leetcode.cn/problems/shun-shi-zhen-da-yin-ju-zhen-lcof/
class Solution {
int mark = 0; // 0:向右 1:向下 2:向左 3:向上
List<Integer> list = new ArrayList<>();
public int[] spiralOrder(int[][] matrix) {
if (matrix.length == 0 || matrix[0].length == 0) {
return new int[0];
}
work(matrix, 0, 0, 0, matrix[0].length - 1, 0, matrix.length - 1);
int[] result = new int[list.size()];
for (int k = 0; k < result.length; k++) {
result[k] = list.get(k);
}
return result;
}
public void work(int[][] matrix, int i, int j, int left, int right, int top, int bottom) {
if (left > right || top > bottom) {
return;
}
list.add(matrix[i][j]);
if (mark == 0) {
if (j < right) {
work(matrix, i, j + 1, left, right, top, bottom);
} else {
top++;
mark = 1;
work(matrix, i + 1, j, left, right, top, bottom);
}
return;
}
if (mark == 1) {
if (i < bottom) {
work(matrix, i + 1, j, left, right, top, bottom);
} else {
right--;
mark = 2;
work(matrix, i, j - 1, left, right, top, bottom);
}
return;
}
if (mark == 2) {
if (j > left) {
work(matrix, i, j - 1, left, right, top, bottom);
} else {
bottom--;
mark = 3;
work(matrix, i - 1, j, left, right, top, bottom);
}
return;
}
if (mark == 3) {
if (i > top) {
work(matrix, i - 1, j, left, right, top, bottom);
} else {
left++;
mark = 0;
work(matrix, i, j + 1, left, right, top, bottom);
}
return;
}
}
}
面试题30:包含min函数的栈
https://leetcode.cn/problems/bao-han-minhan-shu-de-zhan-lcof/
class MinStack {
Stack<Integer> stack1;
Stack<Integer> stack2;
int min;
public MinStack() {
stack1 = new Stack();
stack2 = new Stack();
min = Integer.MAX_VALUE;
}
public void push(int x) {
stack1.push(x);
if (x < min) {
min = x;
}
stack2.push(min);
}
public void pop() {
stack1.pop();
stack2.pop();
if (!stack2.empty()) {
min = stack2.peek();
} else {
min = Integer.MAX_VALUE;
}
}
public int top() {
return stack1.peek();
}
public int min() {
return stack2.peek();
}
}
面试题31:栈的压入、弹出序列
https://leetcode.cn/problems/zhan-de-ya-ru-dan-chu-xu-lie-lcof/
class Solution {
public boolean validateStackSequences(int[] pushed, int[] popped) {
if (pushed.length != popped.length) {
return false;
}
if (pushed.length == 0) {
return true;
}
// 一个数据出栈时,必须是栈顶元素或未进栈元素
Stack<Integer> stack = new Stack<>();
int count = 0;
for (int i = 0; i < popped.length; i++) {
if (stack.contains(popped[i])) {
if (stack.peek() != popped[i]) {
return false;
}
stack.pop();
continue;
}
for (int j = count; j < pushed.length; j++) {
stack.add(pushed[j]);
count++;
if (pushed[j] == popped[i]) {
stack.pop();
break;
}
}
}
if (stack.size() == 0) {
return true;
} else {
return false;
}
}
}
面试题32-1:从上到下打印二叉树
https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-lcof/
class Solution {
List<Integer> list = new ArrayList<>();
Queue<TreeNode> queue = new LinkedList<>();
public int[] levelOrder(TreeNode root) {
if (root == null) {
return new int[0];
}
addNode(root);
while (!queue.isEmpty()) {
addNode(queue.poll());
}
int[] array = new int[list.size()];
for (int i = 0; i < list.size(); i++) {
array[i] = list.get(i);
}
return array;
}
public void addNode(TreeNode node) {
list.add(node.val);
if (node.left != null) {
queue.add(node.left);
}
if (node.right != null) {
queue.add(node.right);
}
}
}
面试题32-2:从上到下打印二叉树2
https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-ii-lcof/
class Solution {
List<List<Integer>> lists = new ArrayList<>(); //result
Map<Integer, List<Integer>> levelListMap = new HashMap<>(); //key:level, value:list
Map<TreeNode, Integer> nodeLevelMap = new HashMap<>(); //key:node, value:level
Queue<TreeNode> queue = new LinkedList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
nodeLevelMap.put(root, 1);
addNode(root);
while (!queue.isEmpty()) {
addNode(queue.poll());
}
for (int i = 1; true; i++) {
if (levelListMap.containsKey(i)) {
lists.add(levelListMap.get(i));
} else {
break;
}
}
return lists;
}
public void addNode(TreeNode node) {
if (!levelListMap.containsKey(nodeLevelMap.get(node))) {
levelListMap.put(nodeLevelMap.get(node), new ArrayList<>());
}
levelListMap.get(nodeLevelMap.get(node)).add(node.val);
if (node.left != null) {
queue.add(node.left);
nodeLevelMap.put(node.left, nodeLevelMap.get(node) + 1);
}
if (node.right != null) {
queue.add(node.right);
nodeLevelMap.put(node.right, nodeLevelMap.get(node) + 1);
}
}
}
面试题32-3:从上到下打印二叉树3
https://leetcode.cn/problems/cong-shang-dao-xia-da-yin-er-cha-shu-iii-lcof/
class Solution {
List<List<Integer>> lists = new ArrayList<>();
Map<Integer, List<Integer>> levelListMap = new HashMap<>(); //key:level, value:list
Map<TreeNode, Integer> nodeLevelMap = new HashMap<>(); //key:node, value:level
Queue<TreeNode> queue = new LinkedList<>();
public List<List<Integer>> levelOrder(TreeNode root) {
if (root == null) {
return new ArrayList<>();
}
nodeLevelMap.put(root, 1);
addNode(root);
while (!queue.isEmpty()) {
addNode(queue.poll());
}
for (int i = 1; true; i++) {
if (levelListMap.containsKey(i)) {
lists.add(levelListMap.get(i));
} else {
break;
}
}
return lists;
}
public void addNode(TreeNode node) {
if (!levelListMap.containsKey(nodeLevelMap.get(node))) {
levelListMap.put(nodeLevelMap.get(node), new ArrayList<>());
}
if (nodeLevelMap.get(node) % 2 == 1) {
levelListMap.get(nodeLevelMap.get(node)).add(node.val);
} else {
levelListMap.get(nodeLevelMap.get(node)).add(0, node.val); //头插入
}
if (node.left != null) {
queue.add(node.left);
nodeLevelMap.put(node.left, nodeLevelMap.get(node) + 1);
}
if (node.right != null) {
queue.add(node.right);
nodeLevelMap.put(node.right, nodeLevelMap.get(node) + 1);
}
}
}
面试题33:二叉搜索树的后序遍历序列
https://leetcode.cn/problems/er-cha-sou-suo-shu-de-hou-xu-bian-li-xu-lie-lcof/
class Solution {
boolean is = true;
public boolean verifyPostorder(int[] postorder) {
if (postorder.length == 0) {
return true;
}
work(postorder, postorder.length - 1);
return is;
}
public void work(int[] postorder, int right) {
if (postorder[0] > postorder[right]) {
for (int i = 0; i < right; i++) {
if (postorder[i] < postorder[right]) {
is = false;
}
}
} else {
boolean change = false;
for (int i = 0; i < right; i++) {
if (postorder[i] > postorder[right]) {
change = true;
}
if (change && postorder[i] < postorder[right]) {
is = false;
}
}
}
if (right > 0) {
work(postorder, right - 1);
}
}
}
面试题34:二叉树中和为某一值的路径
https://leetcode.cn/problems/er-cha-shu-zhong-he-wei-mou-yi-zhi-de-lu-jing-lcof/
class Solution {
List<List<Integer>> lists = new ArrayList<>();
Stack<TreeNode> stack1 = new Stack<>();
Stack<TreeNode> stack2 = new Stack<>();
public List<List<Integer>> pathSum(TreeNode root, int target) {
if (root == null) {
return new ArrayList<>();
}
int currentSum = root.val;
work(root, currentSum, target);
return lists;
}
public void work(TreeNode node, int currentSum, int target) {
stack1.push(node);
if (node.left == null && node.right == null && target - currentSum == 0) {
while (!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
TreeNode tn;
List<Integer> list = new ArrayList<>();
while (!stack2.isEmpty()) {
tn = stack2.pop();
list.add(tn.val);
stack1.push(tn);
}
lists.add(list);
}
if (node.left != null) {
work(node.left, currentSum + node.left.val, target);
}
if (node.right != null) {
work(node.right, currentSum + node.right.val, target);
}
stack1.pop();
}
}
面试题35:复杂链表的复制
https://leetcode.cn/problems/fu-za-lian-biao-de-fu-zhi-lcof/
class Solution {
Map<Node, Node> map = new HashMap<>();
Node p1;
Node p2;
public Node copyRandomList(Node head) {
if (head == null) {
return null;
}
p1 = head;
Node head2 = new Node(0);
p2 = head2;
while (p1 != null) {
p2.next = new Node(p1.val);
p2 = p2.next;
p2.random = p1.random;
map.put(p1, p2);
if (p1.next != null) {
p1 = p1.next;
} else {
p1 = null;
}
}
p2 = head2.next;
while (p2 != null) {
p2.random = map.get(p2.random);
if (p2.next != null) {
p2 = p2.next;
} else {
p2 = null;
}
}
return head2.next;
}
}
面试题36:二叉搜索树与双向链表
https://leetcode.cn/problems/er-cha-sou-suo-shu-yu-shuang-xiang-lian-biao-lcof/
class Solution {
Node pre = null;
Node head;
public Node treeToDoublyList(Node root) {
if (root == null) {
return null;
}
dfs(root);
head.left = pre;
pre.right = head;
return head;
}
public void dfs(Node node) {
if (node == null) {
return;
}
dfs(node.left);
if (head == null) {
head = node;
}
if (pre != null) {
pre.right = node;
node.left = pre;
}
pre = node; // 4
dfs(node.right);
}
}
面试题38:字符串的排列
https://leetcode.cn/problems/zi-fu-chuan-de-pai-lie-lcof/
class Solution {
public String[] permutation(String s) {
if (s.length() == 0) {
return new String[] { "" };
}
char[] chars = s.toCharArray();
Arrays.sort(chars);
Queue<String> queue = new LinkedList<>();
String current;
int currentLength = 0;
for (int i = 0; i < chars.length; i++) {
currentLength++;
if (queue.isEmpty()) {
queue.add(String.valueOf(chars[i]));
continue;
}
while (!queue.isEmpty()) {
if (queue.peek().length() == currentLength) {
break;
}
current = ((LinkedList<String>) queue).pop();
for (int k = 0; k <= current.length(); k++) {
StringBuilder sb = new StringBuilder();
sb.append(current);
sb.insert(k, chars[i]);
queue.add(sb.toString());
}
}
}
Set<String> set = new HashSet<>();
set.addAll(queue);
String[] strs = set.stream().toArray(String[]::new);
return strs;
}
}
4 优化时间和空间效率
面试题39:数组中出现次数超过一半的数字
https://leetcode.cn/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof/
class Solution {
public int majorityElement(int[] nums) {
if (nums.length == 1 || nums.length == 2) {
return nums[0];
}
Arrays.sort(nums);
return nums[nums.length / 2];
}
}
面试题40:最小的k个数
https://leetcode.cn/problems/zui-xiao-de-kge-shu-lcof/
class Solution {
public int[] getLeastNumbers(int[] arr, int k) {
Arrays.sort(arr);
int[] result = new int[k];
for (int i = 0; i < k; i++) {
result[i] = arr[i];
}
return result;
}
}
面试题41:数据流中的中位数
https://leetcode.cn/problems/shu-ju-liu-zhong-de-zhong-wei-shu-lcof/
class MedianFinder {
List<Integer> list;
double median;
public MedianFinder() {
list = new ArrayList<>();
}
public void addNum(int num) {
if (list.size() == 0 || list.get(list.size() - 1) <= num) {
list.add(num);
} else {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) > num) {
list.add(i, num);
break;
}
}
}
}
public double findMedian() {
if (list.size() % 2 == 1) {
median = (double) list.get(list.size() / 2);
} else {
median = (double) (list.get(list.size() / 2 - 1) + list.get(list.size() / 2)) / 2;
}
return median;
}
}
面试题42:连续子数组的最大和
https://leetcode.cn/problems/lian-xu-zi-shu-zu-de-zui-da-he-lcof/
class Solution {
public int maxSubArray(int[] nums) {
int sum = 0;
int maxSum = Integer.MIN_VALUE;
int maxNum = Integer.MIN_VALUE;
for (int i = 0; i < nums.length; i++) {
sum = sum + nums[i];
if (nums[i] > 0 && sum > maxSum) {
maxSum = sum;
}
if (sum < 0) {
sum = 0;
}
if (nums[i] > maxNum) {
maxNum = nums[i];
}
}
if (maxSum < 0) {
maxSum = maxNum;
}
return maxSum;
}
}
面试题44:数字序列中某一位数字
https://leetcode.cn/problems/shu-zi-xu-lie-zhong-mou-yi-wei-de-shu-zi-lcof/
class Solution {
public int findNthDigit(int n) {
if (n < 10) {
return n;
}
long sum = 0L;
long lastSum = 0L;
int k = 0;
while (sum < n) {
lastSum = sum;
sum = (long) (sum + 9 * Math.pow(10, k) * (k + 1));
k++;
}
long rest = n - lastSum;
long begin = (long) Math.pow(10, k - 1);
long result = begin + (rest - 1) / k;
char[] chars = String.valueOf(result).toCharArray();
int index = (int) ((rest - 1) % k);
return (int) Long.parseLong(String.valueOf(chars[index]));
}
}
面试题46:把数字翻译成字符串
https://leetcode.cn/problems/ba-shu-zi-fan-yi-cheng-zi-fu-chuan-lcof/
class Solution {
Map<Integer, Integer> map = new HashMap();
public int translateNum(int num) {
if (num == 0) {
return 1;
}
List<Integer> list = new LinkedList<>();
while (num != 0) {
list.add(0, num % 10);
num = num / 10;
}
return getNum(list, list.size() - 1);
}
public int getNum(List<Integer> list, int index) {
if (map.containsKey(index)) {
return map.get(index);
}
if (index == 0) {
return 1;
}
if (index == 1) {
if ((list.get(index - 1) == 1) || (list.get(index - 1) == 2 && list.get(index) <= 5)) {
return 2;
}
return 1;
}
if ((list.get(index - 1) == 1) || (list.get(index - 1) == 2 && list.get(index) <= 5)) {
map.put(index, getNum(list, index - 1) + getNum(list, index - 2));
} else {
map.put(index, getNum(list, index - 1));
}
return map.get(index);
}
}
面试题47:礼物的最大价值
https://leetcode.cn/problems/li-wu-de-zui-da-jie-zhi-lcof/
class Solution {
Map<String, Integer> map = new HashMap<>();
public int maxValue(int[][] grid) {
if (grid.length < 1 || grid[0].length < 1) {
return 0;
}
int m = grid.length;
int n = grid[0].length;
int result = getValue(grid, m - 1, n - 1);
return result;
}
public int getValue(int[][] grid, int x, int y) {
if (x < 0 || y < 0) {
return 0;
}
if (map.containsKey(x + "," + y)) {
return map.get(x + "," + y);
} else {
map.put(x + "," + y,
grid[x][y] + compare(getValue(grid, x - 1, y), getValue(grid, x, y - 1)));
return map.get(x + "," + y);
}
}
public int compare(int a, int b) {
return a >= b ? a : b;
}
}
面试题48:最长不含重复字符的子字符串
https://leetcode.cn/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/
class Solution {
Set<Character> set = new HashSet<>();
public int lengthOfLongestSubstring(String s) {
if ("".equals(s)) {
return 0;
}
char[] arr = s.toCharArray();
int maxSize = 0;
int begin = 0;
int current = 0;
while (current < arr.length) {
if (!set.contains(arr[current])) {
set.add(arr[current]);
if (maxSize < current - begin + 1) {
maxSize = current - begin + 1;
}
} else {
while (arr[begin] != arr[current]) {
set.remove(arr[begin]);
begin++;
}
begin++;
}
current++;
}
return maxSize;
}
}
面试题49:丑数
https://leetcode.cn/problems/chou-shu-lcof/
class Solution {
public int nthUglyNumber(int n) {
int p2 = 0;
int p3 = 0;
int p5 = 0;
int[] dp = new int[n];
dp[0] = 1;
for(int i = 1; i < n; i++){
dp[i] = Math.min(dp[p2] * 2, Math.min(dp[p3] * 3, dp[p5] * 5));
if(dp[i] == dp[p2] * 2){
p2++;
}
if(dp[i] == dp[p3] * 3){
p3++;
}
if(dp[i] == dp[p5] * 5){
p5++;
}
}
return dp[n - 1];
}
}
面试题50:第一个只出现一次的字符
https://leetcode.cn/problems/di-yi-ge-zhi-chu-xian-yi-ci-de-zi-fu-lcof/
class Solution {
public char firstUniqChar(String s) {
if ("".equals(s)) {
return ' ';
}
char[] cArray = s.toCharArray();
Map<Character, Integer> map = new HashMap<>();
int count;
for (int i = 0; i < cArray.length; i++) {
count = 1;
if (map.containsKey(cArray[i])) {
count = map.get(cArray[i]) + 1;
}
map.put(cArray[i], count);
}
for (int j = 0; j < cArray.length; j++) {
if (map.get(cArray[j]) == 1) {
return cArray[j];
}
}
return ' ';
}
}
面试题52:两个链表的第一个公共节点
https://leetcode.cn/problems/liang-ge-lian-biao-de-di-yi-ge-gong-gong-jie-dian-lcof/
public class Solution {
Stack<ListNode> stack1 = new Stack<>();
Stack<ListNode> stack2 = new Stack<>();
ListNode node1;
ListNode node2;
ListNode result;
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
result = null;
while (headA != null) {
stack1.push(headA);
headA = headA.next != null ? headA.next : null;
}
while (headB != null) {
stack2.push(headB);
headB = headB.next != null ? headB.next : null;
}
while (!stack1.isEmpty() && !stack2.isEmpty()) {
node1 = stack1.pop();
node2 = stack2.pop();
if (node1 != node2) {
return result;
}
result = node1;
}
return result;
}
}
5 综合能力
面试题53-1:在排序数组中查找数字1
https://leetcode.cn/problems/zai-pai-xu-shu-zu-zhong-cha-zhao-shu-zi-lcof/
class Solution {
public static int search(int[] nums, int target) {
if (nums.length == 0) {
return 0;
}
Arrays.sort(nums);
int left = 0;
int right = nums.length - 1;
int mid = left + (right - left) / 2;
int key = binarySearch(nums, target, left, right, mid);
if (key == -1) {
return 0;
} else {
int count = 0;
int cIndex = key;
while (cIndex >= left) {
if (nums[cIndex] == target) {
count++;
cIndex--;
} else {
break;
}
}
cIndex = key + 1;
while (cIndex <= right) {
if (nums[cIndex] == target) {
count++;
cIndex++;
} else {
break;
}
}
return count;
}
}
public static int binarySearch(int[] nums, int target, int left, int right, int mid) {
if (left > right) {
return -1;
}
if (nums[mid] == target) {
return mid;
}
if (nums[mid] > target) {
right = mid - 1;
mid = left + (right - left) / 2;
return binarySearch(nums, target, left, right, mid);
}
if (nums[mid] < target) {
left = mid + 1;
mid = left + (right - left) / 2;
return binarySearch(nums, target, left, right, mid);
}
return -1;
}
}
面试题53-2:0~n-1中缺失的数字
https://leetcode.cn/problems/que-shi-de-shu-zi-lcof/
class Solution {
public int missingNumber(int[] nums) {
if (nums[0] != 0) {
return 0;
}
int sub;
for (int i = 0; i < nums.length - 1; i++) {
sub = nums[i + 1] - nums[i];
if (sub == 2) {
return nums[i] + 1;
}
}
return nums.length;
}
}
面试题54:二叉搜索树的第k大节点
https://leetcode.cn/problems/er-cha-sou-suo-shu-de-di-kda-jie-dian-lcof/
class Solution {
int count = Integer.MIN_VALUE;
TreeNode tn;
public int kthLargest(TreeNode root, int k) {
search(root, k);
return tn.val;
}
public void search(TreeNode node, int k) {
if (node == null) {
return;
}
if (node.right == null && count == Integer.MIN_VALUE) {
count = 1;
}
search(node.right, k);
if (count == k) {
tn = node;
}
count++;
search(node.left, k);
}
}
面试题55-1:二叉树的深度
https://leetcode.cn/problems/er-cha-shu-de-shen-du-lcof/
class Solution {
Map<TreeNode, Integer> map = new HashMap<>();
int maxLevel = Integer.MIN_VALUE;
public int maxDepth(TreeNode root) {
if (root == null) {
return 0;
}
dfs(root, 1);
return maxLevel;
}
public void dfs(TreeNode node, int level) {
if (map.containsKey(node)) {
return;
}
map.put(node, level);
if (maxLevel < level) {
maxLevel = level;
}
if (node.left != null) {
dfs(node.left, level + 1);
}
if (node.right != null) {
dfs(node.right, level + 1);
}
}
}
面试题55-2:平衡二叉树
https://leetcode.cn/problems/ping-heng-er-cha-shu-lcof/
class Solution {
Map<TreeNode, Integer> map = new HashMap<>(); // 记录从每个节点到叶子节点的树高
public boolean isBalanced(TreeNode root) {
if (dfs(root) == -1) {
return false;
} else {
return true;
}
}
public int dfs(TreeNode node) {
if (node == null) {
return 0;
}
if (map.containsKey(node)) {
return map.get(node);
}
int lHeigth = dfs(node.left);
int rHeigth = dfs(node.right);
if (lHeigth == -1 || rHeigth == -1) {
return -1;
}
if (lHeigth - rHeigth > 1 || lHeigth - rHeigth < -1) {
return -1;
}
lHeigth++;
rHeigth++;
map.put(node, bigger(lHeigth, rHeigth));
return map.get(node);
}
public int bigger(int left, int right) {
if (left >= right) {
return left;
} else {
return right;
}
}
}
面试题56-1:数组中数字出现的次数
https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-lcof/
class Solution {
public int[] singleNumbers(int[] nums) {
// 显然,nums.length 大于等于2
int xor = nums[0];
for (int i = 1; i < nums.length; i++) {
xor = xor ^ nums[i];
}
int n = 0;
while (xor != 0) {
xor = xor >> 1;
n++;
}
int left = 0;
int right = nums.length - 1;
int tmp;
while (left <= right) {
if (!indexNIs1(nums[left], n)) {
left++;
continue;
}
if (indexNIs1(nums[right], n)) {
right--;
continue;
}
tmp = nums[left];
nums[left] = nums[right];
nums[right] = tmp;
left++;
right--;
}
int mid = 0;
for (int i = 0; i < nums.length; i++) {
if (indexNIs1(nums[i], n)) {
mid = i;
break;
}
}
int result1 = nums[0];
for (int i = 1; i < mid; i++) {
result1 = result1 ^ nums[i];
}
int result2 = nums[mid];
for (int i = mid + 1; i < nums.length; i++) {
result2 = result2 ^ nums[i];
}
return new int[] { result1, result2 };
}
public boolean indexNIs1(int num, int n) {
return (num >> (n - 1)) % 2 == 1;
}
}
面试题56-2:数组中数字出现的次数II
https://leetcode.cn/problems/shu-zu-zhong-shu-zi-chu-xian-de-ci-shu-ii-lcof/
class Solution {
public int singleNumber(int[] nums) {
if (nums.length == 0) {
return 0;
}
Arrays.sort(nums);
int tmp = Integer.MAX_VALUE;
boolean already = true;
for (int i = 0; i < nums.length; i++) {
if (nums[i] != tmp && already) {
tmp = nums[i];
already = false;
continue;
}
if (nums[i] == tmp) {
already = true;
}
}
return tmp;
}
}
面试题57-1:和为s的两个数字
https://leetcode.cn/problems/he-wei-sde-liang-ge-shu-zi-lcof/
class Solution {
public int[] twoSum(int[] nums, int target) {
Arrays.sort(nums);
int p1 = 0;
int p2 = nums.length - 1;
while (p1 < p2) {
if (target == nums[p1] + nums[p2]) {
return new int[] { nums[p1], nums[p2] };
}
if (target > nums[p1] + nums[p2]) {
p1++;
} else {
p2--;
}
}
return new int[0];
}
}
面试题57-2:和为s的连续正数序列
https://leetcode.cn/problems/he-wei-sde-lian-xu-zheng-shu-xu-lie-lcof/
class Solution {
public int[][] findContinuousSequence(int target) {
// 求最大序列长度times
int sum = 0;
int times = 0;
while (sum < target) {
times++;
sum = sum + times;
}
if (sum != target) {
times--;
}
// 求满足要求的序列长度
List<Integer> list = new ArrayList<>();
for (int i = 2; i <= times; i++) {
if (i % 2 == 0 && target % (target / i + target / i + 1) == 0) {
list.add(i);
}
if (i % 2 == 1 && target % i == 0) {
list.add(i);
}
}
// 按满足要求的序列长度,对target进行拆分
int[][] result = new int[list.size()][];
for (int j = 0; j < list.size(); j++) {
int tmp = list.get(j);
int[] array = new int[tmp];
if (tmp % 2 == 0) {
int base = target / tmp;
int half = tmp / 2;
for (int k = 0; k < array.length; k++) {
array[k] = base - half + 1 + k;
}
}
if (tmp % 2 == 1) {
int base = target / tmp;
int half = tmp / 2;
for (int k = 0; k < array.length; k++) {
array[k] = base - half + k;
}
}
result[list.size() - 1 - j] = array;
}
return result;
}
}
面试题58-1:翻转单词顺序
https://leetcode.cn/problems/fan-zhuan-dan-ci-shun-xu-lcof/
class Solution {
public String reverseWords(String s) {
if ("".equals(s)) {
return "";
}
String[] strings = s.split(" ");
StringBuilder sb = new StringBuilder();
for (int i = strings.length - 1; i >= 0; i--) {
if (!"".equals(strings[i])) {
sb.append(strings[i] + " ");
}
}
return sb.toString().trim();
}
}
面试题58-2:左旋转字符串
https://leetcode.cn/problems/zuo-xuan-zhuan-zi-fu-chuan-lcof/
class Solution {
public String reverseLeftWords(String s, int n) {
if (n >= s.length()) {
return s;
}
String s1 = s.substring(0, n);
String s2 = s.substring(n);
return s2 + s1;
}
}
面试题61:扑克牌中的顺子
https://leetcode.cn/problems/bu-ke-pai-zhong-de-shun-zi-lcof/
class Solution {
Set<Integer> set = new HashSet<>();
public boolean isStraight(int[] nums) {
int max = Integer.MIN_VALUE;
int min = Integer.MAX_VALUE;
int count0 = 0;
int tmp;
for (int i = 0; i < nums.length; i++) {
tmp = nums[i];
if (tmp < 0 || tmp > 13) {
return false;
}
if (tmp != 0) {
if (set.contains(tmp)) {
return false;
}
set.add(tmp);
if (tmp > max) {
max = tmp;
}
if (tmp < min) {
min = tmp;
}
} else {
count0++;
if (count0 == 5) {
return true;
}
}
}
return max - min + 1 <= 5;
}
}
面试题63:股票的最大利润
https://leetcode.cn/problems/gu-piao-de-zui-da-li-run-lcof/
class Solution {
public int maxProfit(int[] prices) {
if (prices.length <= 1) {
return 0;
}
int maxProfit = Integer.MIN_VALUE;
int sum = 0;
int[] subPrices = new int[prices.length - 1];
for (int i = 0; i < prices.length - 1; i++) {
subPrices[i] = prices[i + 1] - prices[i];
}
for (int j = 0; j < subPrices.length; j++) {
sum = sum + subPrices[j];
if (sum < 0) {
sum = 0;
}
if (sum > maxProfit) {
maxProfit = sum;
}
}
return maxProfit;
}
}
面试题64:求1+2+…+n
https://leetcode.cn/problems/qiu-12n-lcof/
class Solution {
public int sumNums(int n) {
int sum = 0;
boolean bool = n > 0 && (sum = n + sumNums(n - 1)) > 0;
return sum;
}
}
面试题65:不用加减乘除做加法
https://leetcode.cn/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/
class Solution {
public int add(int a, int b) {
int sum;
int carry;
while (b != 0) {
sum = a ^ b;
carry = (a & b) << 1;
a = sum;
b = carry;
}
return a;
}
}
面试题66:构建乘积数组
https://leetcode.cn/problems/gou-jian-cheng-ji-shu-zu-lcof/
class Solution {
Map<Integer, Integer> map = new HashMap<>();
public int[] constructArr(int[] a) {
if (a.length == 0) {
return new int[] {};
}
if (a.length == 1) {
return new int[] { 1 };
}
int leftTotal = 1;
int current = 0;
int[] b = new int[a.length];
while (current < a.length) {
int rightTotal = 1;
if (map.containsKey(current + 1)) {
rightTotal = map.get(current + 1);
} else {
for (int i = a.length - 1; i > current; i--) {
rightTotal *= a[i];
map.put(i, rightTotal);
}
}
b[current] = leftTotal * rightTotal;
leftTotal *= a[current];
current++;
}
return b;
}
}
面试题68-1:二叉搜索树的最近公共祖先
https://leetcode.cn/problems/er-cha-sou-suo-shu-de-zui-jin-gong-gong-zu-xian-lcof/
class Solution {
TreeNode current;
TreeNode result;
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (p.val > q.val) {
current = p;
p = q;
q = current;
}
current = root;
work(current, p, q);
return result;
}
public void work(TreeNode current, TreeNode p, TreeNode q) {
if (current.val > p.val && current.val < q.val) {
result = current;
} else if (current.val == p.val) {
result = p;
} else if (current.val == q.val) {
result = q;
} else if (current.val > p.val && current.val > q.val) {
work(current.left, p, q);
} else if (current.val < p.val && current.val < q.val) {
work(current.right, p, q);
}
}
}
面试题68-2:二叉树的最近公共祖先
https://leetcode.cn/problems/er-cha-shu-de-zui-jin-gong-gong-zu-xian-lcof/
class Solution {
Stack<TreeNode> stack = new Stack<>();
List<TreeNode> path1 = new ArrayList<>();
List<TreeNode> path2 = new ArrayList<>();
public TreeNode lowestCommonAncestor(TreeNode root, TreeNode p, TreeNode q) {
if (root == null) {
return null;
}
dfs(root, p, q);
TreeNode common = root;
int index = 0;
while (index < path1.size() && index < path2.size()) {
if (path1.get(index) == path2.get(index)) {
common = path1.get(index);
}
index++;
}
return common;
}
public void dfs(TreeNode node, TreeNode p, TreeNode q) {
stack.push(node);
if (node.val == p.val) {
path1.addAll(stack);
}
if (node.val == q.val) {
path2.addAll(stack);
}
if (node.left != null) {
dfs(node.left, p, q);
}
if (node.right != null) {
dfs(node.right, p, q);
}
stack.pop();
}
}