function getPrimes(max) {
// create undefined array
let arr = new Array(max).fill(undefined);
// fill true for (prime) index i and
// fill false for any index that can be multiplied by i
// prime number start from 2
for (let i = 2; i < max; i++) {
if (arr[i] === undefined) arr[i] = true;
for (let j = i + i; j < max; j += i) {
arr[j] = false;
}
}
// return index(prime number) and filter out all false
return arr.map((item, index) => item ? index : false)
.filter(Boolean);
}
// generate all prime numbers that less than 15000
// the 10001st prime number should lay in that range
let primes = getPrimes(150000); // The number lay in that range
console.log(primes[10000]); // The 10001th prime
You are given the root of a binary tree containing digits from 0 to 9 only.
Each root-to-leaf path in the tree represents a number.
For example, the root-to-leaf path 1 -> 2 -> 3 represents the number 123.
Return the total sum of all root-to-leaf numbers.
A leaf node is a node with no children.
Example 1:
Input: root = [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:
Input: root = [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.
Constraints:
The number of nodes in the tree is in the range [1, 1000].
0 <= Node.val <= 9
The depth of the tree will not exceed 10.
Idea:
Use DFS Template
Solution 1:
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {TreeNode} root
* @return {number}
*/
var sumNumbers = function(root) {
if (root === null) return;
let res = [];
let cur = [];
dfs(root, res, cur);
let sum = 0;
for (let num of res) {
sum += num;
}
return sum;
};
function dfs(root, res, cur) {
// exit recursion:
if (root === null) return;
// found leaf, save the number
if (root.left === null && root.right === null) {
cur.push(root.val);
res.push(parseInt(cur.join('')));
cur.pop();
return;
}
// possible solution
if (root !== null) {
cur.push(root.val);
dfs(root.left, res, cur);
dfs(root.right, res, cur);
cur.pop();
}
return;
}
Solution 2: (Version 2)
var sumNumbers = function(root) {
if (root === null) return;
let res = [0];
let cur = [0];
dfs(root, res, cur);
return res[0];
};
function dfs(root, res, cur) {
// exit recursion:
if (root === null) return;
// found leaf, save the number
if (root.left === null && root.right === null) {
cur[0] = cur[0] * 10 + root.val;
res[0] += cur[0];
cur[0] = (cur[0] - root.val) / 10;
return;
}
// possible solution
if (root !== null) {
cur[0] = cur[0] * 10 + root.val;
dfs(root.left, res, cur);
dfs(root.right, res, cur);
cur[0] = (cur[0] - root.val) / 10;
}
return;
}
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night.
Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.
Example 1:
Input: nums = [1,2,3,1]
Output: 4
Explanation: Rob house 1 (money = 1) and then rob house 3 (money = 3).
Total amount you can rob = 1 + 3 = 4.
Example 2:
Input: nums = [2,7,9,3,1]
Output: 12
Explanation: Rob house 1 (money = 2), rob house 3 (money = 9) and rob house 5 (money = 1).
Total amount you can rob = 2 + 9 + 1 = 12.
Constraints:
1 <= nums.length <= 100
0 <= nums[i] <= 400
Idea:
Dynamic Programing
Try to look for a pattern, see comments in the code.
Solution:
/**
* @param {number[]} nums
* @return {number}
*/
var rob = function(nums) {
// one house
if (nums.length === 1) return nums[0];
// dp[i] = max money can be taken after visited i houses
let dp = new Array(nums.length);
dp[1] = nums[0];
dp[2] = Math.max(nums[0], nums[1]);
// two houses
if (nums.length === 2) return dp[2];
// more houses - try to look for a pattern
// dp[3] = Math.max(dp[2], dp[1] + nums[2]);
// dp[4] = Math.max(dp[3], dp[2] + nums[3]);
// ...
for (let i = 3; i <= nums.length; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
}
return dp[nums.length];
};
/**
* @param {number[]} numbers
* @param {number} target
* @return {number[]}
*/
var twoSum = function(numbers, target) {
let l = 0;
let r = numbers.length - 1;
while (l < r) {
let sum = numbers[l] + numbers[r];
if (sum === target) break;
else if (sum > target) r--;
else l++;
}
// this question use 1-indexed
return [l + 1, r + 1];
};
Solution 2: (Hash table)
var twoSum = function(numbers, target) {
let map = new Map;
for (var i = 0; i < numbers.length; i++) {
var diff = target - numbers[i];
if(map.has(diff)) {
return [map.get(diff), i + 1];
}
map.set(numbers[i], i + 1);
}
};
/**
* @param {number[][]} matrix
* @param {number} target
* @return {boolean}
*/
var searchMatrix = function(matrix, target) {
return dfs(matrix, target, 0, 0);
};
function dfs(matrix, target, x, y) {
let rows = matrix.length;
let cols = matrix[0].length;
// exit recursion condition, reach to the end;
if (y === rows) return false;
// traverse from left to right, then next row
let nextX = (x + 1) % cols;
let nextY = nextX === 0 ? y + 1 : y;
// found return true or not found, DFS next element
if (matrix[y][x] === target)
return true;
else
return dfs(matrix, target, nextX, nextY);
return false;
}
Solution 2: (Binary Search) Better and Faster!
Time complexity: O(log(mn))
Space complexity: O(1)
var searchMatrix = function(matrix, target) {
let cols = matrix[0].length;
// treat 2D as 1D, use binary search
let l = 0;
let r = matrix.length * cols;
while (l < r) {
let mid = l + Math.floor((r - l) / 2);
let row = Math.floor(mid / cols);
let col = mid % cols;
if (matrix[row][col] === target) {
return true;
} else if (matrix[row][col] > target) {
r = mid;
} else {
l = mid + 1;
}
}
return false;
};
Write a program to solve a Sudoku puzzle by filling the empty cells.
A sudoku solution must satisfy all of the following rules:
Each of the digits 1-9 must occur exactly once in each row.
Each of the digits 1-9 must occur exactly once in each column.
Each of the digits 1-9 must occur exactly once in each of the 9 3x3 sub-boxes of the grid.
The '.' character indicates empty cells.
Example 1:
Input: board = [["5","3",".",".","7",".",".",".","."],["6",".",".","1","9","5",".",".","."],[".","9","8",".",".",".",".","6","."],["8",".",".",".","6",".",".",".","3"],["4",".",".","8",".","3",".",".","1"],["7",".",".",".","2",".",".",".","6"],[".","6",".",".",".",".","2","8","."],[".",".",".","4","1","9",".",".","5"],[".",".",".",".","8",".",".","7","9"]]
Output: [["5","3","4","6","7","8","9","1","2"],["6","7","2","1","9","5","3","4","8"],["1","9","8","3","4","2","5","6","7"],["8","5","9","7","6","1","4","2","3"],["4","2","6","8","5","3","7","9","1"],["7","1","3","9","2","4","8","5","6"],["9","6","1","5","3","7","2","8","4"],["2","8","7","4","1","9","6","3","5"],["3","4","5","2","8","6","1","7","9"]]
Explanation: The input board is shown above and the only valid solution is shown below:
Constraints:
board.length == 9
board[i].length == 9
board[i][j] is a digit or '.'.
It is guaranteed that the input board has only one solution.
Idea:
Create 3 tracking arrays:
1 - 9 occur once in whole row, whole col, whole box.[ith row][number] [ith col][number] [ith box][number]ex: [ith row][N] = 1 means ith row already use number N
DFS/Backtracking
Travese the board from left to right, row by row
Try to fill 1-9, success return,
if not success, recover data and try next element
Solution:
/**
* @param {character[][]} board
* @return {void} Do not return anything, modify board in-place instead.
*/
var solveSudoku = function(board) {
// 1 - 9 occur once in whole row, whole col, whole box
// [ith row][number] [ith col][number] [ith box][number]
// ex: [ith row][N] = 1 means ith row already use number N
let rows = Array.from(new Array(9), () => new Array(10).fill(0));
let cols = Array.from(new Array(9), () => new Array(10).fill(0));
let boxes = Array.from(new Array(9), () => new Array(10).fill(0));
for (let i = 0; i < 9; i++) {
for (let j = 0; j < 9; j++) {
const c = board[i][j];
if (c !== '.') {
let num = parseInt(c);
let bx = Math.floor(j / 3);
let by = Math.floor(i / 3);
rows[i][num] = 1;
cols[j][num] = 1;
boxes[by * 3 + bx][num] = 1;
}
}
}
dfs(board, 0, 0, rows, cols, boxes);
};
function dfs(board, x, y, rows, cols, boxes) {
// exit recursion condition, reach to the end;
if (y === 9) return true;
// traverse from left to right, then next row
let nextX = (x + 1) % 9;
let nextY = nextX === 0 ? y + 1 : y;
// already has number, DFS next element
if (board[y][x] !== '.') return dfs(board, nextX, nextY, rows, cols, boxes);
// fill number from 1 - 9
for (let i = 1; i <= 9; i++) {
let bx = Math.floor(x / 3);
let by = Math.floor(y / 3);
let box_index = by * 3 + bx;
// if not breaking the following 3 rules
if (!rows[y][i] && !cols[x][i] && !boxes[box_index][i]) {
// modify, fill the number
rows[y][i] = 1;
cols[x][i] = 1;
boxes[box_index][i] = 1;
board[y][x] = i.toString();
// Try to fill next element, if success return true, or recover
if (dfs(board, nextX, nextY, rows, cols, boxes)) return true;
// recover data
board[y][x] = '.';
boxes[box_index][i] = 0;
cols[x][i] = 0;
rows[y][i] = 0;
}
}
return false;
}
Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.
An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
Traverse connected components: Use DFS to traverse 4 directions and mark them “0” if found “1”
Solution:
/**
* @param {character[][]} grid
* @return {number}
*/
var numIslands = function(grid) {
let row = grid.length;
if (row === 0) return 0;
let col = grid[0].length;
let res = 0;
for (let x = 0; x < col ; x++) {
for (let y = 0; y < row; y++) {
if (grid[y][x] === "1") {
res++;
dfs(grid, x, y, col, row);
}
}
}
return res;
};
var dfs = function(grid, x, y, n, m) {
// over boundry cases and not "1" => return
if (x < 0 || y < 0 || x >= n || y >= m || grid[y][x] === "0") return;
// already visited mark it "0"
grid[y][x] = "0";
// traverse 4 directions if any "1" => mark them "0"
dfs(grid, x + 1, y, n, m);
dfs(grid, x - 1, y, n, m);
dfs(grid, x, y + 1, n, m);
dfs(grid, x, y - 1, n, m);
}
Given the head of a singly linked list, reverse the list, and return the reversed list.
Example 1:
Input: head = [1,2,3,4,5]
Output: [5,4,3,2,1]
Example 2:
Input: head = [1,2]
Output: [2,1]
Example 3:
Input: head = []
Output: []
Constraints:
The number of nodes in the list is the range [0, 5000].
-5000 <= Node.val <= 5000
Idea: 背口诀
reverse LinkedList 口诀: create newHead and next
next -> head.next -> newHead.next -> head -> next
Solution:
/**
* Definition for singly-linked list.
* function ListNode(val, next) {
* this.val = (val===undefined ? 0 : val)
* this.next = (next===undefined ? null : next)
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var reverseList = function(head) {
// empty or only one node
if (head === null || head.next === null) return head;
let newHead = new ListNode();
let next = new ListNode();
while (head !== null) {
// next helper create
next = head.next;
// disconnect, and point to newHead.next
head.next = newHead.next;
// move newHead.next to head
newHead.next = head;
// move head to next location
head = next;
}
return newHead.next;
};