Leetcode medium
class GeneNode { String gene; int numOfSteps; public GeneNode(String gene, int steps) { this.gene = gene; this.numOfSteps = steps; } } public int minMutation(String start, String end, String[] bank) { if(bank == null || bank.length == 0) return -1; if(start == end) return 0; char[] geneSet = {'A', 'C', 'G', 'T'}; Set<String> bankSet = new HashSet<>(Arrays.asList(bank)); Queue<GeneNode> toExplore = new LinkedList<>(); toExplore.add(new GeneNode(start, 0)); while(!toExplore.isEmpty()) { GeneNode curr = toExplore.poll(); if(curr.gene.equals(end)) { return curr.numOfSteps; } char[] word = curr.gene.toCharArray(); for(int i = 0; i < word.length; i++) { for(int j = 0; j < geneSet.length; j++) { char tmp = word[i]; if(word[i] != geneSet[j]) { word[i] = geneSet[j]; } String needle = new String(word); if(bankSet.contains(needle)) { toExplore.add(new GeneNode(needle, curr.numOfSteps + 1)); bankSet.remove(needle); } word[i] = tmp; } } } return -1; }
A gene string can be represented by an 8-character long string, with choices from "A", "C", "G", "T". Suppose we need to investigate about a mutation (mutation from "start" to "end"), where ONE mutation is defined as ONE single character changed in the gene string. For example, "AACCGGTT" -> "AACCGGTA" is 1 mutation. Also, there is a given gene "bank", which records all the valid gene mutations. A gene must be in the bank to make it a valid gene string. Now, given 3 things - start, end, bank, your task is to determine what is the minimum number of mutations needed to mutate from "start" to "end". If there is no such a mutation, return -1. Note: Starting point is assumed to be valid, so it might not be included in the bank. If multiple mutations are needed, all mutations during in the sequence must be valid. You may assume start and end string is not the same. Example 1: start: "AACCGGTT" end: "AACCGGTA" bank: ["AACCGGTA"] return: 1 Example 2: start: "AACCGGTT" end: "AAACGGTA" bank: ["AACCGGTA", "AACCGCTA", "AAACGGTA"] return: 2
public int findPeakElement(int[] nums) { if(nums.length <= 1) return 0; int peak = 0; for(int i = 0; i < nums.length; i++) { if(isPeak(nums, i)) { peak = i; } } return peak; } private boolean isPeak(int[] nums, int curr) { if(curr == 0) { return nums[curr] > nums[curr + 1]; } else if(curr == nums.length - 1) { return nums[curr] > nums[curr - 1]; } else { return nums[curr] > nums[curr - 1] && nums[curr] > nums[curr + 1]; } }
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: Input: nums = [1,2,3,1] Output: 2 Explanation: 3 is a peak element and your function should return the index number 2.
public int uniquePaths(int m, int n) { // recursion //if(m <= 0 || n <= 0) return 0; //if(m == 1 || n == 1) return 1; //return uniquePaths(m - 1, n) + uniquePaths(m, n - 1); int[][] dp = new int[m][n]; for(int i = 0; i < m; i++) { dp[i][0] = 1; } for(int j = 0; j < n; j++) { dp[0][j] = 1; } for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } return dp[m - 1][n - 1]; }
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). How many possible unique paths are there? Note: m and n will be at most 100. Example 1: Input: m = 3, n = 2 Output: 3 Explanation: From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: 1. Right -> Right -> Down 2. Right -> Down -> Right 3. Down -> Right -> Right
public int uniquePathsWithObstacles(int[][] obstacleGrid) { int m = obstacleGrid.length; int n = obstacleGrid[0].length; int[][] dp = new int[m][n]; for(int i = 0; i < m && obstacleGrid[i][0] != 1; i++) { dp[i][0] = 1; } for(int j = 0; j < n && obstacleGrid[0][j] != 1; j++) { dp[0][j] = 1; } for(int i = 1; i < m; i++) { for(int j = 1; j < n; j++) { if(obstacleGrid[i][j] != 1) { dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; } } } return dp[m - 1][n - 1]; }
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). Now consider if some obstacles are added to the grids. How many unique paths would there be? An obstacle and empty space is marked as 1 and 0 respectively in the grid. Note: m and n will be at most 100. Example 1: Input: [ [0,0,0], [0,1,0], [0,0,0] ] Output: 2 Explanation: There is one obstacle in the middle of the 3x3 grid above. There are two ways to reach the bottom-right corner: 1. Right -> Right -> Down -> Down 2. Down -> Down -> Right -> Right
public List<String> findRepeatedDnaSequences(String s) { Map<String, Integer> map = new HashMap<>(); List<String> result = new ArrayList<>(); for(int i = 0; i + 10 < s.length(); i++) { String needle = s.substring(i, i + 10); if(map.containsKey(needle)) { map.put(needle, map.get(needle) + 1); } else { map.put(needle, 1); } } for(Map.Entry<String, Integer> entry : map.entrySet()) { if(entry.getValue() > 1) { result.add(entry.getKey()); } } return result; }
All DNA is composed of a series of nucleotides abbreviated as A, C, G, and T, for example: "ACGAATTCCG". When studying DNA, it is sometimes useful to identify repeated sequences within the DNA. Write a function to find all the 10-letter-long sequences (substrings) that occur more than once in a DNA molecule. Example: Input: s = "AAAAACCCCCAAAAACCCCCCAAAAAGGGTTT" Output: ["AAAAACCCCC", "CCCCCAAAAA"]
public UndirectedGraphNode cloneGraph(UndirectedGraphNode node) { if(node == null) return null; Map<UndirectedGraphNode, UndirectedGraphNode> map = new HashMap(); // origin node : copied node UndirectedGraphNode myNode = new UndirectedGraphNode(node.label); // copy map.put(node, myNode); Queue<UndirectedGraphNode> q = new LinkedList(); // origin nodes q.add(node); // bfs traverse graph while (!q.isEmpty()) { UndirectedGraphNode cur = q.poll(); // all neighbors of current origin node for (UndirectedGraphNode neighbor : cur.neighbors) { // if the origin node is not visited if (!map.containsKey(neighbor)) { map.put(neighbor, new UndirectedGraphNode(neighbor.label)); // to avoid loop, we just add the unvisited node to queue q.offer(neighbor); } // add neighbors to the copied node // copied node: map.get(cur) -> copied node of cur // neighbors: map.get(neighbor) -> copied node of neighbor map.get(cur).neighbors.add(map.get(neighbor)); } } return myNode; }
Clone an undirected graph. Each node in the graph contains a label and a list of its neighbors. OJ's undirected graph serialization: Nodes are labeled uniquely. We use # as a separator for each node, and , as a separator for node label and each neighbor of the node. As an example, consider the serialized graph {0,1,2#1,2#2,2}. The graph has a total of three nodes, and therefore contains three parts as separated by #. First node is labeled as 0. Connect node 0 to both nodes 1 and 2. Second node is labeled as 1. Connect node 1 to node 2. Third node is labeled as 2. Connect node 2 to node 2 (itself), thus forming a self-cycle. Visually, the graph looks like the following: 1 / \ / \ 0 --- 2 / \ \_/
public int compareVersion(String version1, String version2) { String[] v1 = version1.split("\\."); String[] v2 = version2.split("\\."); int i = 0; while (i < Math.min(v1.length, v2.length)) { if (Integer.parseInt(v1[i]) < Integer.parseInt(v2[i])) { return -1; } else if (Integer.parseInt(v1[i]) > Integer.parseInt(v2[i])) { return 1; } else { i++; } } while (i < v1.length) { if (Integer.parseInt(v1[i]) > 0) { return 1; } else { i++; } } while (i < v2.length) { if (Integer.parseInt(v2[i]) > 0) { return -1; } else { i++; } } return 0; }
Compare two version numbers version1 and version2. If version1 > version2 return 1; if version1 < version2 return -1;otherwise return 0. You may assume that the version strings are non-empty and contain only digits and the . character. The . character does not represent a decimal point and is used to separate number sequences. For instance, 2.5 is not "two and a half" or "half way to version three", it is the fifth second-level revision of the second first-level revision. Example 1: Input: version1 = "0.1", version2 = "1.1" Output: -1 Example 2: Input: version1 = "1.0.1", version2 = "1" Output: 1 Example 3: Input: version1 = "7.5.2.4", version2 = "7.5.3" Output: -1
class WordDictionary { private class TrieNode { Map<Character, TrieNode> children; boolean endOfWord; public TrieNode() { children = new HashMap<>(); endOfWord = false; } } private TrieNode root; /** Initialize your data structure here. */ public WordDictionary() { root = new TrieNode(); } /** Adds a word into the data structure. */ public void addWord(String word) { TrieNode curr = root; for(int i = 0; i < word.length(); i++) { char c = word.charAt(i); TrieNode node = curr.children.get(c); if(node == null) { node = new TrieNode(); curr.children.put(c, node); } curr = node; } curr.endOfWord = true; } /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */ public boolean search(String word) { return search(word, 0, root); } private boolean search(String word, int index, TrieNode node) { if(index == word.length()) return node.endOfWord; char c = word.charAt(index); if(c != '.') { return node.children.get(c) != null && search(word, index + 1, node.children.get(c)); } else { for(char i = 'a'; i <= 'z'; i++) { if(node.children.get(i) != null && search(word, index + 1, node.children.get(i))) return true; } } return false; } }
Design a data structure that supports the following two operations: void addWord(word) bool search(word) search(word) can search a literal word or a regular expression string containing only letters a-z or .. A . means it can represent any one letter. Example: addWord("bad") addWord("dad") addWord("mad") search("pad") -> false search("bad") -> true search(".ad") -> true search("b..") -> true Note: You may assume that all words are consist of lowercase letters a-z.
public boolean isValidSudoku(char[][] board) { Set<String> set = new HashSet<>(); for (int row = 0; row < board.length; row++) { for (int col = 0; col < board[row].length; col++) { char val = board[row][col]; if (val != '.') { int block = (row / 3 * 3) + (col / 3); if (set.contains("r" + row + val) || set.contains("c" + col + val) || set.contains("b" + block + val)) return false; else { set.add("r" + row + val); set.add("c" + col + val); set.add("b" + block + val); } } } } return true; }
Determine if a 9x9 Sudoku board is valid. Only the filled cells need to be validated according to the following rules: Each row must contain the digits 1-9 without repetition. Each column must contain the digits 1-9 without repetition. Each of the 9 3x3 sub-boxes of the grid must contain the digits 1-9 without repetition. A partially filled sudoku which is valid. The Sudoku board could be partially filled, where empty cells are filled with the character '.'. Example 1: Input: [ ["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: true
// Approach #1 // Using Arrays.sort directly. class Solution { public int findKthLargest(int[] nums, int k) { Arrays.sort(nums); return nums[nums.length - k]; } } // Approach #2 // Use built-in Priority Queue. class Solution { public int findKthLargest(int[] nums, int k) { Queue<Integer> q = new PriorityQueue<>((n1, n2) -> (n2 - n1)); for (int num : nums) { q.offer(num); } for (int i = 0; i < k - 1; i++) { q.poll(); } return (int)q.poll(); } }
Find the kth largest element in an unsorted array. Note that it is the kth largest element in the sorted order, not the kth distinct element. Example 1: Input: [3,2,1,5,6,4] and k = 2 Output: 5
public int maximalSquare(char[][] matrix) { if (matrix.length == 0) return 0; int[][] dp = new int[matrix.length][matrix[0].length]; int max = 0; for (int i = matrix.length - 1; i >= 0; i--) { for (int j = matrix[0].length - 1; j >= 0; j--) { if (matrix[i][j] == '0') { dp[i][j] = 0; } else if (i == matrix.length - 1 || j == matrix[0].length - 1) { dp[i][j] = 1; } else { dp[i][j] = Math.min(Math.min(dp[i + 1][j], dp[i][j + 1]), dp[i + 1][j + 1]) + 1; } max = Math.max(dp[i][j], max); } } return max * max; }
Given a 2D binary matrix filled with 0's and 1's, find the largest square containing only 1's and return its area. Example: Input: 1 0 1 0 0 1 0 1 1 1 1 1 1 1 1 1 0 0 1 0 Output: 4
public int kthSmallest(TreeNode root, int k) { if(root == null) return -1; List<Integer> resultList = new ArrayList<>(); inOrder(root, k, resultList); return resultList.get(k - 1); } public void inOrder(TreeNode root, int k, List<Integer> list) { if(root == null) return; inOrder(root.left, k, list); if(list.size() == k) return; list.add(root.val); inOrder(root.right, k, list); }
Given a binary search tree, write a function kthSmallest to find the kth smallest element in it. Note: You may assume k is always valid, 1 ≤ k ≤ BST's total elements. Example 1: Input: root = [3,1,4,null,2], k = 1 3 / \ 1 4 \ 2 Output: 1
public void connect(TreeLinkNode root) { if(root == null) return; connectNodes(root, null); } private void connectNodes(TreeLinkNode root, TreeLinkNode nextNode) { if(root == null) return; root.next = nextNode; connectNodes(root.left, root.right); if(root.next != null) { connectNodes(root.right, root.next.left); } else { connectNodes(root.right, null); } }
Given a binary tree struct TreeLinkNode { TreeLinkNode *left; TreeLinkNode *right; TreeLinkNode *next; } Populate each next pointer to point to its next right node. If there is no next right node, the next pointer should be set to NULL. Initially, all next pointers are set to NULL. Note: You may only use constant extra space. Recursive approach is fine, implicit stack space does not count as extra space for this problem. You may assume that it is a perfect binary tree (ie, all leaves are at the same level, and every parent has two children). Example: Given the following perfect binary tree, 1 / \ 2 3 / \ / \ 4 5 6 7 After calling your function, the tree should look like: 1 -> NULL / \ 2 -> 3 -> NULL / \ / \ 4->5->6->7 -> NULL
public List<List<Integer>> pathSum(TreeNode root, int sum) { List<List<Integer>> result = new ArrayList<>(); List<Integer> currList = new ArrayList<>(); if(root == null) return result; pathSum(root, sum, result, currList); return result; } private void pathSum(TreeNode root, int sum, List<List<Integer>> result, List<Integer> currList) { if(root == null) { return; } if(root.left == null && root.right == null) { if(root.val == sum) { currList.add(root.val); result.add(new ArrayList<>(currList)); currList.remove(currList.size() - 1); } } currList.add(root.val); pathSum(root.left, sum - root.val, result, currList); pathSum(root.right, sum - root.val, result, currList); currList.remove(currList.size() - 1); }
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, 5 / \ 4 8 / / \ 11 13 4 / \ / \ 7 2 5 1 Return: [ [5,4,11,2], [5,8,4,5] ]
Idea is to do a level order traversal and in each step pass along the ((parent x 10) + child ) as the current value. If it ends up being a leaf node add it to the sum. public int sumNumbers(TreeNode root) { if(root==null) return 0; Queue<TreeNode> q = new LinkedList<>(); q.add(root); int sum=0; while(!q.isEmpty()){ TreeNode node = q.poll(); int current = node.val; if(node.left==null && node.right==null) sum+=current; if(node.left!=null){ node.left.val = current*10+node.left.val; q.add(node.left); } if(node.right!=null){ node.right.val = current*10+node.right.val; q.add(node.right); } } return sum; }
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: 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.
public boolean isValidBST(TreeNode root) { return isValidBST(root, Long.MIN_VALUE, Long.MAX_VALUE); } private boolean isValidBST(TreeNode root, long left, long right) { if(root == null) return true; if(root.val <= left || root.val >= right) { return false; } return isValidBST(root.left, left, root.val) && isValidBST(root.right, root.val, right); }
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: Input: 2 / \ 1 3 Output: true
private TreeNode prev = null; public void flatten(TreeNode root) { if (root == null) return; flatten(root.right); flatten(root.left); root.right = prev; root.left = null; prev = root; }
Given a binary tree, flatten it to a linked list in-place. For example, given the following tree: 1 / \ 2 5 / \ \ 3 4 6 The flattened tree should look like: 1 \ 2 \ 3 \ 4 \ 5 \ 6
public List<Integer> preorderTraversal(TreeNode root) { List<Integer> result = new ArrayList<>(); preorderTraversal(root, result); return result; } // private void preorderTraversal(TreeNode root, List<Integer> result) { // if(root == null) return; // result.add(root.val); // preorderTraversal(root.left, result); // preorderTraversal(root.right, result); // } private void preorderTraversal(TreeNode root, List<Integer> result) { Stack<TreeNode> stack = new Stack<>(); stack.push(root); while (!stack.isEmpty()) { TreeNode current = stack.pop(); if (current == null) continue; result.add(current.val); stack.push(current.right); stack.push(current.left); } }
Given a binary tree, return the preorder traversal of its nodes' values. Example: Input: [1,null,2,3] 1 \ 2 / 3 Output: [1,2,3] Follow up: Recursive solution is trivial, could you do it iteratively?
public List<List<Integer>> combinationSum2(int[] nums, int target) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, target, 0); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){ if(remain < 0) return; else if(remain == 0) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < nums.length; i++){ if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates tempList.add(nums[i]); backtrack(list, tempList, nums, remain - nums[i], i + 1); tempList.remove(tempList.size() - 1); } } }
Given a collection of candidate numbers (candidates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. Each number in candidates may only be used once in the combination. Note: All numbers (including target) will be positive integers. The solution set must not contain duplicate combinations. Example 1: Input: candidates = [10,1,2,7,6,1,5], target = 8, A solution set is: [ [1, 7], [1, 2, 5], [2, 6], [1, 1, 6] ] Example 2: Input: candidates = [2,5,2,1,2], target = 5, A solution set is: [ [1,2,2], [5] ]
public List<List<Integer>> permute(int[] nums) { List<List<Integer>> list = new ArrayList<>(); // Arrays.sort(nums); // not necessary backtrack(list, new ArrayList<>(), nums); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums){ if(tempList.size() == nums.length){ list.add(new ArrayList<>(tempList)); } else{ for(int i = 0; i < nums.length; i++){ if(tempList.contains(nums[i])) continue; // element already exists, skip tempList.add(nums[i]); backtrack(list, tempList, nums); tempList.remove(tempList.size() - 1); } } }
Given a collection of distinct integers, return all possible permutations. Example: Input: [1,2,3] Output: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
public List<List<Integer>> subsetsWithDup(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, 0); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int start){ list.add(new ArrayList<>(tempList)); for(int i = start; i < nums.length; i++){ if(i > start && nums[i] == nums[i-1]) continue; // skip duplicates tempList.add(nums[i]); backtrack(list, tempList, nums, i + 1); tempList.remove(tempList.size() - 1); } }
Given a collection of integers that might contain duplicates, nums, return all possible subsets (the power set). Note: The solution set must not contain duplicate subsets. Example: Input: [1,2,2] Output: [ [2], [1], [1,2,2], [2,2], [1,2], [] ]
public List<Interval> merge(List<Interval> intervals) { Comparator<Interval> comp = new Comparator<Interval>() { public int compare(Interval v1, Interval v2) { int startCom = v1.start - v2.start; if(startCom != 0) return startCom; else return v1.end - v2.end; } }; Collections.sort(intervals, comp); Stack<Interval> stack = new Stack<>(); for(int i = 0; i < intervals.size(); i++) { if(stack.isEmpty()) { stack.push(intervals.get(i)); } else { Interval v1 = stack.pop(); Interval v2 = intervals.get(i); // when v2 start date is less then v1 end date if(v1.end >= v2.start && v1.end <= v2.end) { Interval v3 = new Interval(v1.start, v2.end); stack.push(v3); } // when v2 is inside v1, // which means both start and end dates of v2 less than v1.end else if(v1.end >= v2.start && v1.end >= v2.end) { stack.push(v1); } else { stack.push(v1); stack.push(v2); } } } return new ArrayList<>(stack); }
Given a collection of intervals, merge all overlapping intervals. Example 1: Input: [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explanation: Since intervals [1,3] and [2,6] overlaps, merge them into [1,6]. Example 2: Input: [[1,4],[4,5]] Output: [[1,5]] Explanation: Intervals [1,4] and [4,5] are considerred overlapping.
public List<List<Integer>> permuteUnique(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, new boolean[nums.length]); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, boolean [] used){ if(tempList.size() == nums.length){ list.add(new ArrayList<>(tempList)); } else{ for(int i = 0; i < nums.length; i++){ if(used[i] || i > 0 && nums[i] == nums[i-1] && !used[i - 1]) continue; used[i] = true; tempList.add(nums[i]); backtrack(list, tempList, nums, used); used[i] = false; tempList.remove(tempList.size() - 1); } } }
Given a collection of numbers that might contain duplicates, return all possible unique permutations. Example: Input: [1,1,2] Output: [ [1,1,2], [1,2,1], [2,1,1] ]
public int countNodes(TreeNode root) { if(root == null) return 0; int left = height(root); if(left < 0) return 0; if(height(root.right) == left - 1) { return (int) Math.pow(2, left) + countNodes(root.right); } return (int) Math.pow(2, left - 1) + countNodes(root.left); } private int height(TreeNode root){ if(root == null) return -1; return 1 + height(root.left); } Explanation The height of a tree can be found by just going left. Let a single node tree have height 0. Find the height h of the whole tree. If the whole tree is empty, i.e., has height -1, there are 0 nodes. Otherwise check whether the height of the right subtree is just one less than that of the whole tree, meaning left and right subtree have the same height. If yes, then the last node on the last tree row is in the right subtree and the left subtree is a full tree of height h-1. So we take the 2^h-1 nodes of the left subtree plus the 1 root node plus recursively the number of nodes in the right subtree. If no, then the last node on the last tree row is in the left subtree and the right subtree is a full tree of height h-2. So we take the 2^(h-1)-1 nodes of the right subtree plus the 1 root node plus recursively the number of nodes in the left subtree. Since I halve the tree in every recursive step, I have O(log(n)) steps. Finding a height costs O(log(n)). So overall O(log(n)^2).
Given a complete binary tree, count the number of nodes. Note: Definition of a complete binary tree from Wikipedia: In a complete binary tree every level, except possibly the last, is completely filled, and all nodes in the last level are as far left as possible. It can have between 1 and 2h nodes inclusive at the last level h. Example: Input: 1 / \ 2 3 / \ / 4 5 6 Output: 6
public ListNode partition(ListNode head, int x) { if(head == null) return head; ListNode result = new ListNode(0); ListNode resultHead = result; ListNode curr = head; // work on smaller vals first while(curr != null) { if(curr.val < x) { result.next = new ListNode(curr.val); result = result.next; } curr = curr.next; } // work on greater than or equal while(head != null) { if(head.val >= x) { result.next = new ListNode(head.val); result = result.next; } head = head.next; } return resultHead.next; }
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x. You should preserve the original relative order of the nodes in each of the two partitions. Example: Input: head = 1->4->3->2->5->2, x = 3 Output: 1->2->2->4->3->5
public ListNode removeNthFromEnd(ListNode head, int n) { ListNode tmp = head; int size = 0; while(tmp != null) { size++; tmp = tmp.next; } ListNode runner = null; ListNode runnerHead = null; int counter = 0; while(head != null) { if(counter != size - n) { if(runner == null) { runner = new ListNode(head.val); runnerHead = runner; } else { runner.next = new ListNode(head.val); runner = runner.next; } } head = head.next; counter++; } return runnerHead; }
Given a linked list, remove the n-th node from the end of list and return its head. Example: Given linked list: 1->2->3->4->5, and n = 2. After removing the second node from the end, the linked list becomes 1->2->3->5.
List<String> res = new ArrayList<>(); Map<String, List<String>> map = new HashMap<>(); public List<String> findItinerary(String[][] tickets) { for (String[] airports : tickets) { if (!map.containsKey(airports[0])) { map.put(airports[0], new ArrayList<>()); } map.get(airports[0]).add(airports[1]); } for (String str : map.keySet()) { Collections.sort(map.get(str)); } dfs("JFK"); return res; } private void dfs(String from) { if (!map.containsKey(from) || map.get(from).size() == 0) { res.add(0, from); return; } while (map.get(from).size() > 0) { String to = map.get(from).remove(0); dfs(to); } res.add(0, from); }
Given a list of airline tickets represented by pairs of departure and arrival airports [from, to], reconstruct the itinerary in order. All of the tickets belong to a man who departs from JFK. Thus, the itinerary must begin with JFK. Note: If there are multiple valid itineraries, you should return the itinerary that has the smallest lexical order when read as a single string. For example, the itinerary ["JFK", "LGA"] has a smaller lexical order than ["JFK", "LGB"]. All airports are represented by three capital letters (IATA code). You may assume all tickets form at least one valid itinerary. Example 1: Input: tickets = [["MUC", "LHR"], ["JFK", "MUC"], ["SFO", "SJC"], ["LHR", "SFO"]] Output: ["JFK", "MUC", "LHR", "SFO", "SJC"]
private class LargerNumberComparator implements Comparator<String> { @Override public int compare(String a, String b) { String order1 = a + b; String order2 = b + a; return order2.compareTo(order1); } } public String largestNumber(int[] nums) { // Get input integers as strings. String[] asStrs = new String[nums.length]; for (int i = 0; i < nums.length; i++) { asStrs[i] = String.valueOf(nums[i]); } // Sort strings according to custom comparator. Arrays.sort(asStrs, new LargerNumberComparator()); // If, after being sorted, the largest number is `0`, the entire number // is zero. if (asStrs[0].equals("0")) { return "0"; } // Build largest number from sorted array. String largestNumberStr = new String(); for (String numAsStr : asStrs) { largestNumberStr += numAsStr; } return largestNumberStr; }
Given a list of non negative integers, arrange them such that they form the largest number. Example 1: Input: [10,2] Output: "210" Example 2: Input: [3,30,34,5,9] Output: "9534330"
public static int minPathSum(int[][] grid) { int m = grid.length, n = grid[0].length; int[] dp = new int[n+1]; for (int j = 0; j < n; j++) dp[j+1] = dp[j] + grid[0][j]; dp[0] = Integer.MAX_VALUE; for (int i=1; i<m; i++){ for (int j=0; j<n; j++){ dp[j+1] = Math.min(dp[j], dp[j+1]) + grid[i][j]; } } return dp[n]; }
Given a m x n grid filled with non-negative numbers, find a path from top left to bottom right which minimizes the sum of all numbers along its path. Note: You can only move either down or right at any point in time. Example: Input: [ [1,3,1], [1,5,1], [4,2,1] ] Output: 7 Explanation: Because the path 1→3→1→1→1 minimizes the sum.
public void setZeroes(int[][] matrix) { int m = matrix.length; int n = matrix[0].length; boolean[][] isZero = new boolean[m][n]; for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if(matrix[i][j] == 0) isZero[i][j] = true; } } for(int i = 0; i < m; i++) { for(int j = 0; j < n; j++) { if(isZero[i][j]) { int counter = 0; while(counter < m) { matrix[counter][j] = 0; counter++; } counter = 0; while(counter < n) { matrix[i][counter] = 0; counter++; } } } } }
Given a m x n matrix, if an element is 0, set its entire row and column to 0. Do it in-place. Example 1: Input: [ [1,1,1], [1,0,1], [1,1,1] ] Output: [ [1,0,1], [0,0,0], [1,0,1] ]
public int kthSmallest(int[][] matrix, int k) { int[] table = new int[matrix.length * matrix[0].length]; int count = 0; for(int i = 0; i < matrix.length; i++) { for(int j = 0; j < matrix[0].length; j++) { table[count++] = matrix[i][j]; } } Arrays.sort(table); return table[k - 1]; }
Given a n x n matrix where each of the rows and columns are sorted in ascending order, find the kth smallest element in the matrix. Note that it is the kth smallest element in the sorted order, not the kth distinct element. Example: matrix = [ [ 1, 5, 9], [10, 11, 13], [12, 13, 15] ], k = 8, return 13.
This problem is essentially let us to find whether there are several numbers in a set which are able to sum to a specific value (in this problem, the value is sum/2). Actually, this is a 0/1 knapsack problem, for each number, we can pick it or not. Let us assume dp[i][j] means whether the specific sum j can be gotten from the first i numbers. If we can pick such a series of numbers from 0-i whose sum is j, dp[i][j] is true, otherwise it is false. Base case: dp[0][0] is true; (zero number consists of sum 0 is true) Transition function: For each number, if we don't pick it, dp[i][j] = dp[i-1][j], which means if the first i-1 elements has made it to j, dp[i][j] would also make it to j (we can just ignore nums[i]). If we pick nums[i]. dp[i][j] = dp[i-1][j-nums[i]], which represents that j is composed of the current value nums[i] and the remaining composed of other previous numbers. Thus, the transition function is dp[i][j] = dp[i-1][j] || dp[i-1][j-nums[i]] public boolean canPartition(int[] nums) { int sum = 0; for (int num : nums) { sum += num; } if (sum % 2 == 1) { return false; } sum /= 2; int n = nums.length; boolean[] dp = new boolean[sum+1]; dp[0] = true; for (int num : nums) { for (int i = sum; i > 0; i--) { if (i >= num) { dp[i] = dp[i] || dp[i-num]; } } } return dp[sum]; }
Given a non-empty array containing only positive integers, find if the array can be partitioned into two subsets such that the sum of elements in both subsets is equal. Note: Each of the array element will not exceed 100. The array size will not exceed 200. Example 1: Input: [1, 5, 11, 5] Output: true Explanation: The array can be partitioned as [1, 5, 5] and [11]. Example 2: Input: [1, 2, 3, 5] Output: false Explanation: The array cannot be partitioned into equal sum subsets.
class Pair implements Comparable<Pair> { int val; int count; public Pair(int v, int c) { val = v; count = c; } public int compareTo(Pair that) { return that.count - this.count; } } public class Solution { public List<Integer> topKFrequent(int[] nums, int k) { Map<Integer, Integer> map = new HashMap<>(); for(int i = 0; i < nums.length; i++) { map.put(nums[i], map.containsKey(nums[i]) ? map.get(nums[i]) + 1 : 1); } PriorityQueue<Pair> pq = new PriorityQueue<>(); for(Map.Entry<Integer, Integer> entry : map.entrySet()) { pq.add(new Pair(entry.getKey(), entry.getValue())); } List<Integer> result = new ArrayList<Integer>(); while(k > 0) { result.add(pq.poll().val); k--; } return result; } }
Given a non-empty array of integers, return the k most frequent elements. Example 1: Input: nums = [1,1,1,2,2,3], k = 2 Output: [1,2] Example 2: Input: nums = [1], k = 1 Output: [1] Note: You may assume k is always valid, 1 ≤ k ≤ number of unique elements. Your algorithm's time complexity must be better than O(n log n), where n is the array's size.
where n is number of digits and each digit place is filled with 0 to 9 based on position if n==1 10^1=10 where exclusive 10 so 9 digits if n>10 no unique digits possible as we have only 10 digits if n==0 10^0=1 so only 0 is digit and answer is 1 for n between 2 to 10 _ _ _ _ _ _ _ _ _ _ preceding 0 is not allowed so 9 digits there in rest position for n=10 9 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 x 1 for n=9 9 x 9 x 8 x 7 x 6 x 5 x 4 x 3 x 2 for n=8 9 x 9 x 8 x 7 x 6 x 5 x 4 x 3 for n=7 9 x 9 x 8 x 7 x 6 x 5 x 4 similarly it goes... public int countNumbersWithUniqueDigits(int n) { int i, ans = 0; if(n==0) return 1; if(n==10) return 9; if(n>10) return 0; for(i = 1; i <= n; i++) { if(i == 1) { ans = ans+10; } else { int j = i-1, temp = 9, u = 9; while(j > 0) { temp = temp * u; u--; j--; } ans = ans + temp; } } return ans; }
Given a non-negative integer n, count all numbers with unique digits, x, where 0 ≤ x < 10n. Example: Input: 2 Output: 91 Explanation: The answer should be the total numbers in the range of 0 ≤ x < 100, excluding 11,22,33,44,55,66,77,88,99
public int integerReplacement(long n){ if(n == 1) return 0; if(n % 2 == 0) return integerReplacement( n / 2 ) + 1 ; else return Math.min(integerReplacement(n + 1) + 1, integerReplacement(n - 1) + 1); }
Given a positive integer n and you can do operations as follow: If n is even, replace n with n/2. If n is odd, you can replace n with either n + 1 or n - 1. What is the minimum number of replacements needed for n to become 1? Example 1: Input: 8 Output: 3 Explanation: 8 -> 4 -> 2 -> 1 Example 2: Input: 7 Output: 4 Explanation: 7 -> 8 -> 4 -> 2 -> 1 or 7 -> 6 -> 3 -> 2 -> 1
Assuming A[i] is the least number of perfect square numbers summing to i A[1] = 1 A[i] = 1 + min(A[i-j^2]), for all j's such that 1 < j^2 <= i public int numSquares(int n) { int[] A = new int[n+1]; // A[i] = least number of perfect square numbers summing to i A[1] = 1; // base case, takes one "step" (1^2) to get to 1 for (int i = 2; i < n+1; i++) { // populate A at each index // find smallest of A[i-1], A[i-4], A[i-9] ... A[i-j^2], stopping when j^2 > i int minSteps = Integer.MAX_VALUE; int j = 1; while (j*j <= i) { if (A[i-j*j] < minSteps) { minSteps = A[i-j*j]; } j++; } A[i] = minSteps+1; // add one "step" to smallest square one step below it } return A[n]; }
Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n. Example 1: Input: n = 12 Output: 3 Explanation: 12 = 4 + 4 + 4. Example 2: Input: n = 13 Output: 2 Explanation: 13 = 4 + 9.
public List<List<Integer>> combinationSum(int[] nums, int target) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, target, 0); return list; } private void backtrack(List<List<Integer>> list, List<Integer> tempList, int [] nums, int remain, int start){ if(remain < 0) return; else if(remain == 0) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < nums.length; i++){ tempList.add(nums[i]); backtrack(list, tempList, nums, remain - nums[i], i); // not i + 1 because we can reuse same elements tempList.remove(tempList.size() - 1); } } }
Given a set of candidate numbers (candidates) (without duplicates) and a target number (target), find all unique combinations in candidates where the candidate numbers sums to target. The same repeated number may be chosen from candidates unlimited number of times. Note: All numbers (including target) will be positive integers. The solution set must not contain duplicate combinations. Example 1: Input: candidates = [2,3,6,7], target = 7, A solution set is: [ [7], [2,2,3] ]
public List<List<Integer>> subsets(int[] nums) { List<List<Integer>> list = new ArrayList<>(); Arrays.sort(nums); backtrack(list, new ArrayList<>(), nums, 0); return list; } private void backtrack(List<List<Integer>> list , List<Integer> tempList, int [] nums, int start){ list.add(new ArrayList<>(tempList)); for(int i = start; i < nums.length; i++){ tempList.add(nums[i]); backtrack(list, tempList, nums, i + 1); tempList.remove(tempList.size() - 1); } }
Given a set of distinct integers, nums, return all possible subsets (the power set). Note: The solution set must not contain duplicate subsets. Example: Input: nums = [1,2,3] Output: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
public ListNode oddEvenList(ListNode head) { if(head == null) return null; if(head.next == null) return head; ListNode odd = new ListNode(head.val); ListNode even = new ListNode(head.next.val); ListNode result = odd; ListNode evenHead = even; head = head.next.next; int count = 1; while(head != null) { ListNode tmp = new ListNode(head.val); if(count % 2 != 0) { odd.next = tmp; odd = odd.next; } else { even.next = tmp; even = even.next; } count++; head = head.next; } odd.next = evenHead; return result; }
Given a singly linked list, group all odd nodes together followed by the even nodes. Please note here we are talking about the node number and not the value in the nodes. You should try to do it in place. The program should run in O(1) space complexity and O(nodes) time complexity. Example 1: Input: 1->2->3->4->5->NULL Output: 1->3->5->2->4->NULL Example 2: Input: 2->1->3->5->6->4->7->NULL Output: 2->3->6->7->1->5->4->NULL
Just go through the numbers and include those in the result that haven't been included twice already. public int removeDuplicates(int[] nums) { int i = 0; for (int n : nums) if (i < 2 || n > nums[i-2]) nums[i++] = n; return i; }
Given a sorted array nums, remove the duplicates in-place such that duplicates appeared at most twice 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: Given nums = [1,1,1,2,2,3], Your function should return length = 5, with the first five elements of nums being 1, 1, 2, 2 and 3 respectively. It doesn't matter what you leave beyond the returned length.
// O(n^2) public int maxProduct(String[] words) { int max = 0; if(words == null || words.length == 0) return max; for(int i = 0; i < words.length; i++) { for(int j = 0; j != i && j < words.length; j++) { if(!haveCommonChars(words[i], words[j])) { max = Math.max(max, words[i].length() * words[j].length()); } } } return max; } // O(m + n) private boolean haveCommonChars(String s1, String s2) { Map<Character, Integer> map = new HashMap<>(); for(int i = 0; i < s1.length(); i++) { char c = s1.charAt(i); map.put(c, 1); } for(int i = 0; i < s2.length(); i++) { char c = s2.charAt(i); if(map.containsKey(c)) return true; } return false; }
Given a string array words, find the maximum value of length(word[i]) * length(word[j]) where the two words do not share common letters. You may assume that each word will contain only lower case letters. If no such two words exist, return 0. Example 1: Input: ["abcw","baz","foo","bar","xtfn","abcdef"] Output: 16 Explanation: The two words can be "abcw", "xtfn". Example 2: Input: ["a","ab","abc","d","cd","bcd","abcd"] Output: 4 Explanation: The two words can be "ab", "cd".
public boolean isSubsequence(String s, String t) { if(s.length() == 0) return true; int i = 0; int j = 0; while(i < s.length() && j < t.length()) { if(s.charAt(i) == t.charAt(j)) { i++; } j++; if(i == s.length()) return true; } return false; }
Given a string s and a string t, check if s is subsequence of t. You may assume that there is only lower case English letters in both s and t. t is potentially a very long (length ~= 500,000) string, and s is a short string (<=100). A subsequence of a string is a new string which is formed from the original string by deleting some (can be none) of the characters without disturbing the relative positions of the remaining characters. (ie, "ace" is a subsequence of "abcde" while "aec" is not). Example 1: s = "abc", t = "ahbgdc" Return true. Example 2: s = "axc", t = "ahbgdc" Return false. Follow up: If there are lots of incoming S, say S1, S2, ... , Sk where k >= 1B, and you want to check one by one to see if T has its subsequence. In this scenario, how would you change your code?
We observe that a palindrome mirrors around its center. Therefore, a palindrome can be expanded from its center, and there are only 2n - 12n−1 such centers. public String longestPalindrome(String s) { if (s == null || s.length() < 1) return ""; int start = 0, end = 0; for (int i = 0; i < s.length(); i++) { int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i + 1); int len = Math.max(len1, len2); if (len > end - start) { start = i - (len - 1) / 2; end = i + len / 2; } } return s.substring(start, end + 1); } private int expandAroundCenter(String s, int left, int right) { int L = left, R = right; while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) { L--; R++; } return R - L - 1; } Time complexity : O(n^2). Since expanding a palindrome around its center could take O(n) time, the overall complexity is O(n^2) Space complexity : O(1).
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000. Example 1: Input: "babad" Output: "bab" Note: "aba" is also a valid answer.
public List<List<String>> partition(String s) { List<List<String>> list = new ArrayList<>(); backtrack(list, new ArrayList<>(), s, 0); return list; } public void backtrack(List<List<String>> list, List<String> tempList, String s, int start){ if(start == s.length()) list.add(new ArrayList<>(tempList)); else{ for(int i = start; i < s.length(); i++){ if(isPalindrome(s, start, i)){ tempList.add(s.substring(start, i + 1)); backtrack(list, tempList, s, i + 1); tempList.remove(tempList.size() - 1); } } } } public boolean isPalindrome(String s, int low, int high){ while(low < high) if(s.charAt(low++) != s.charAt(high--)) return false; return true; }
Given a string s, partition s such that every substring of the partition is a palindrome. Return all possible palindrome partitioning of s. Example: Input: "aab" Output: [ ["aa","b"], ["a","a","b"] ]
public int lengthOfLongestSubstring(String s) { if(s == null || s.equals("")) return 0; if(s.length() == 1) return 1; int max = Integer.MIN_VALUE; Map<Character, Integer> map = new HashMap<>(); for(int i = 0; i < s.length(); i++) { char c = s.charAt(i); if(map.containsKey(c)) { max = Math.max(map.size(), max); i = map.get(c) + 1; c = s.charAt(i); map.clear(); } map.put(c, i); } max = Math.max(map.size(), max); return max; }
Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is "b", with the length of 1. Given "pwwkew", the answer is "wke", with the length of 3. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.
public static int minimumTotal(List<List<Integer>> triangle) { int[] A = new int[triangle.size()+1]; for(int i=triangle.size()-1;i>=0;i--){ for(int j=0;j<triangle.get(i).size();j++){ A[j] = Math.min(A[j],A[j+1]) + triangle.get(i).get(j); } } return A[0]; }
Given a triangle, find the minimum path sum from top to bottom. Each step you may move to adjacent numbers on the row below. For example, given the following triangle [ [2], [3,4], [6,5,7], [4,1,8,3] ] The minimum path sum from top to bottom is 11 (i.e., 2 + 3 + 5 + 1 = 11).
public int countBattleships(char[][] board) { if(board == null || board.length == 0) return 0; int result = 0; for(int i = 0; i < board.length; i++) { for(int j = 0; j < board[0].length; j++) { if(board[i][j] == 'X') { result++; dfs(board, i, j); } } } return result; } private void dfs(char[][] board, int i, int j) { if(i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] == '.') { return; } board[i][j] = '.'; dfs(board, i + 1, j); dfs(board, i, j + 1); }
Given an 2D board, count how many battleships are in it. The battleships are represented with 'X's, empty slots are represented with '.'s. You may assume the following rules: You receive a valid board, made of only battleships or empty slots. Battleships can only be placed horizontally or vertically. In other words, they can only be made of the shape 1xN (1 row, N columns) or Nx1 (N rows, 1 column), where N can be of any size. At least one horizontal or vertical cell separates between two battleships - there are no adjacent battleships. Example: X..X ...X ...X In the above board there are 2 battleships. Invalid Example: ...X XXXX ...X This is an invalid board that you will not receive - as battleships will always have a cell separating between them. Follow up: Could you do it in one-pass, using only O(1) extra memory and without modifying the value of the board?
The main idea is the same with problem Linked List Cycle II,https://leetcode.com/problems/linked-list-cycle-ii/. Use two pointers the fast and the slow. The fast one goes forward two steps each time, while the slow one goes only step each time. They must meet the same item when slow==fast. In fact, they meet in a circle, the duplicate number must be the entry point of the circle when visiting the array from nums[0]. Next we just need to find the entry point. We use a point(we can use the fast one before) to visit form begining with one step each time, do the same job to slow. When fast==slow, they meet at the entry point of the circle. The easy understood code is as follows. public int findDuplicate(int[] nums) { if(nums.length <= 0) return -1; int slow = nums[0]; int fast = nums[nums[0]]; while(slow != fast) { slow = nums[slow]; fast = nums[nums[fast]]; } fast = 0; while(fast != slow) { fast = nums[fast]; slow = nums[slow]; } return slow; }
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one. Example 1: Input: [1,3,4,2,2] Output: 2 Example 2: Input: [3,1,3,4,2] Output: 3 Note: You must not modify the array (assume the array is read only). You must use only constant, O(1) extra space. Your runtime complexity should be less than O(n2). There is only one duplicate number in the array, but it could be repeated more than once.
public List<List<Integer>> threeSum(int[] num) { Arrays.sort(num); List<List<Integer>> res = new LinkedList<>(); for (int i = 0; i < num.length-2; i++) { if (i == 0 || (i > 0 && num[i] != num[i-1])) { int lo = i+1, hi = num.length-1, sum = 0 - num[i]; while (lo < hi) { if (num[lo] + num[hi] == sum) { res.add(Arrays.asList(num[i], num[lo], num[hi])); while (lo < hi && num[lo] == num[lo+1]) lo++; while (lo < hi && num[hi] == num[hi-1]) hi--; lo++; hi--; } else if (num[lo] + num[hi] < sum) lo++; else hi--; } } } return res; }
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: Given array nums = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
public int[] searchRange(int[] nums, int target) { int lo = 0; int hi = nums.length - 1; int[] result = {-1, -1}; while(lo < hi) { int mid = lo + (hi - lo) / 2; if(target > nums[mid]) { lo = mid + 1; } else if(target < nums[mid]) { hi = mid - 1; } else { int left = mid; int right = mid; while(nums[left] == target) left--; while(nums[right] == target) right++; result[0] = left + 1; result[1] = right - 1; break; } } return result; }
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: Input: nums = [5,7,7,8,8,10], target = 8 Output: [3,4] Example 2: Input: nums = [5,7,7,8,8,10], target = 6 Output: [-1,-1]
private Map<Integer, List<Integer>> places; private Random r; public Solution(int[] nums) { places = new HashMap<>(); r = new Random(); for (int i = 0; i < nums.length; i++) { List<Integer> locs = places.getOrDefault(nums[i], new ArrayList<>()); locs.add(i); places.put(nums[i], locs); } } public int pick(int target) { List<Integer> locs = places.get(target); return locs.get(r.nextInt(locs.size())); }
Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array. Note: The array size can be very large. Solution that uses too much extra space will not pass the judge. Example: int[] nums = new int[] {1,2,3,3,3}; Solution solution = new Solution(nums); // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning. solution.pick(3); // pick(1) should return 0. Since in the array only nums[0] is equal to 1. solution.pick(1);
// O(n) solution public int minSubArrayLen(int s, int[] nums) { if(nums == null || nums.length == 0) return 0; int i = 0, j = 0, sum = 0, result = Integer.MAX_VALUE; while(i < nums.length){ sum += nums[i]; while(sum >= s){ result = Math.min(result, i - j + 1); sum -= nums[j]; j++; } i++; } return result == Integer.MAX_VALUE ? 0 : result; }
Given an array of n positive integers and a positive integer s, find the minimal length of a contiguous subarray of which the sum ≥ s. If there isn't one, return 0 instead. Example: Input: s = 7, nums = [2,3,1,2,4,3] Output: 2 Explanation: the subarray [4,3] has the minimal length under the problem constraint. Follow up: If you have figured out the O(n) solution, try coding another solution of which the time complexity is O(n log n).
public boolean canJump(int[] nums) { int max = 0; for(int i = 0; i < nums.length; i++) { if(i > max) return false; max = Math.max(nums[i] + i, max); } return true; }
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: Input: [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: Input: [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.
public List<List<String>> groupAnagrams(String[] strs) { List<List<String>> result = new ArrayList<>(); Map<String, List<String>> map = new HashMap<>(); for(String s : strs) { char[] c = s.toCharArray(); Arrays.sort(c); String keyStr = new String(c); if(!map.containsKey(keyStr)) { map.put(keyStr, new ArrayList<>()); } map.get(keyStr).add(s); } result.addAll(map.values()); return result; }
Given an array of strings, group anagrams together. Example: Input: ["eat", "tea", "tan", "ate", "nat", "bat"], Output: [ ["ate","eat","tea"], ["nat","tan"], ["bat"] ]
public String decodeString(String s) { Stack<String> stack = new Stack<>(); int time = 0; for (char c : s.toCharArray()) { if (c >= '0' && c <= '9') time = (time * 10) + (c - '0'); else if (c == '[') { stack.push(time + ""); stack.push("["); time = 0; } else if (c == ']') { StringBuilder temp = new StringBuilder(); while (stack.peek() != "[") { temp.insert(0, stack.pop()); } stack.pop(); // skip "[" int t = Integer.parseInt(stack.pop()); String str = temp.toString(); // do t-1 times while (t-- > 1) { temp.append(str); } stack.push(temp.toString()); } else stack.push(c+""); } StringBuilder sb = new StringBuilder(); while (!stack.isEmpty()) { sb.insert(0, stack.pop()); } return sb.toString(); }
Given an encoded string, return it's decoded string. The encoding rule is: k[encoded_string], where the encoded_string inside the square brackets is being repeated exactly k times. Note that k is guaranteed to be a positive integer. You may assume that the input string is always valid; No extra white spaces, square brackets are well-formed, etc. Furthermore, you may assume that the original data does not contain any digits and that digits are only for those repeat numbers, k. For example, there won't be input like 3a or 2[4]. Examples: s = "3[a]2[bc]", return "aaabcbc". s = "3[a2[c]]", return "accaccacc". s = "2[abc]3[cd]ef", return "abcabccdcdcdef".
public String reverseWords(String s) { s = s.trim(); if(s == null || s.length() <= 1) return s; char[] arr = s.toCharArray(); reverse(arr, 0, arr.length - 1); int j = 0; for(int i = 0; i < arr.length; i++) { if(arr[i] == ' ') { reverse(arr, j, i - 1); j = i + 1; } } reverse(arr, j, arr.length - 1); return new String(arr); } private void reverse(char[] arr, int start, int end) { while(start <= end) { char tmp = arr[start]; arr[start] = arr[end]; arr[end] = tmp; start++; end--; } }
Given an input string, reverse the string word by word. Example: Input: "the sky is blue", Output: "blue is sky the". 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.
Boyer-Moore Majority Vote algorithm generalization public List<Integer> majorityElement(int[] nums) { //there should be at most 2 different elements in nums more than n/3 //so we can find at most 2 elements based on Boyer-Moore Majority Vote algo List<Integer> result = new ArrayList<Integer>(); if(nums.length == 0) return result; int count1 = 0, count2 = 0, m1 = 0, m2 = 0; for(int n : nums) { if(m1 == n) count1++; else if(m2 == n) count2++; else if(count1 == 0) { m1 = n; count1 = 1; } else if(count2 == 0) { m2 = n; count2 = 1; } else{ count1--; count2--; } } count1 = 0; count2 = 0; //count the number for the 2 elements for(int n : nums){ if(n == m1) count1++; else if(n == m2) count2++; } //if those appear more than n/3 if(count1 > nums.length / 3) result.add(m1); if(count2 > nums.length / 3) result.add(m2); return result; }
Given an integer array of size n, find all elements that appear more than ⌊ n/3 ⌋ times. Note: The algorithm should run in linear time and in O(1) space. Example 1: Input: [3,2,3] Output: [3]
Convert each number into a string. Sort. (Strings automatically sorted by lexicographically). Convert back to int. public List<Integer> lexicalOrder(int n) { String[] strs = new String[n]; for(int i = 1; i <= n; i++) { strs[i - 1] = "" + i; } Arrays.sort(strs); List<Integer> result = new ArrayList<>(); for(String s : strs) { result.add(Integer.parseInt(s)); } return result; }
Given an integer n, return 1 - n in lexicographical order. For example, given 13, return: [1,10,11,12,13,2,3,4,5,6,7,8,9]. Please optimize your algorithm to use less time and space. The input size may be as large as 5,000,000.
public boolean increasingTriplet(int[] nums) { if(nums == null || nums.length <= 2) return false; int min = Integer.MAX_VALUE; int secondMin = Integer.MAX_VALUE; for(int i = 0; i < nums.length; i++) { if(nums[i] <= min) { min = nums[i]; } else if(nums[i] < secondMin) { secondMin = nums[i]; } else if(nums[i] > secondMin) return true; } return false; }
Given an unsorted array return whether an increasing subsequence of length 3 exists or not in the array. Formally the function should: Return true if there exists i, j, k such that arr[i] < arr[j] < arr[k] given 0 ≤ i < j < k ≤ n-1 else return false. Note: Your algorithm should run in O(n) time complexity and O(1) space complexity. Example 1: Input: [1,2,3,4,5] Output: true
public int maxArea(int[] height) { int lo = 0; int hi = height.length - 1; int max = -1; while(lo < hi) { // area of the ractangle is // min height * number of bars (= hi - lo) max = Math.max(max, Math.min(height[lo], height[hi]) * (hi - lo)); if(height[lo] < height[hi]) { lo++; } else { hi--; } } return max; }
Given n non-negative integers a1, a2, ..., an , where each represents a point at coordinate (i, ai). n vertical lines are drawn such that the two endpoints of line i is at (i, ai) and (i, 0). Find two lines, which together with x-axis forms a container, such that the container contains the most water.
public List<String> generateParenthesis(int n) { List<String> result = new ArrayList<>(); char[] str = new char[n * 2]; int left = n; int right = n; generateParens(left, right, result, str, 0); return result; } private void generateParens(int left, int right, List<String> result, char[] str, int index) { if(left < 0 || right < left) return; if(left == 0 && right == 0) { result.add(new String(str)); } else { str[index] = '('; generateParens(left - 1, right, result, str, index + 1); str[index] = ')'; generateParens(left, right - 1, result, str, index + 1); } }
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: [ "((()))", "(()())", "(())()", "()(())", "()()()" ]
The problem can be solved in a dynamic programming way. I'll explain the intuition and formulas in the following. Given a sequence 1...n, to construct a Binary Search Tree (BST) out of the sequence, we could enumerate each number i in the sequence, and use the number as the root, naturally, the subsequence 1...(i-1) on its left side would lay on the left branch of the root, and similarly the right subsequence (i+1)...n lay on the right branch of the root. We then can construct the subtree from the subsequence recursively. Through the above approach, we could ensure that the BST that we construct are all unique, since they have unique roots. The problem is to calculate the number of unique BST. To do so, we need to define two functions: G(n): the number of unique BST for a sequence of length n. F(i, n), 1 <= i <= n: the number of unique BST, where the number i is the root of BST, and the sequence ranges from 1 to n. As one can see, G(n) is the actual function we need to calculate in order to solve the problem. And G(n) can be derived from F(i, n), which at the end, would recursively refer to G(n). First of all, given the above definitions, we can see that the total number of unique BST G(n), is the sum of BST F(i) using each number i as a root. i.e. G(n) = F(1, n) + F(2, n) + ... + F(n, n). Particularly, the bottom cases, there is only one combination to construct a BST out of a sequence of length 1 (only a root) or 0 (empty tree). i.e. G(0)=1, G(1)=1. Given a sequence 1...n, we pick a number i out of the sequence as the root, then the number of unique BST with the specified root F(i), is the cartesian product of the number of BST for its left and right subtrees. For example, F(3, 7): the number of unique BST tree with number 3 as its root. To construct an unique BST out of the entire sequence [1, 2, 3, 4, 5, 6, 7] with 3 as the root, which is to say, we need to construct an unique BST out of its left subsequence [1, 2] and another BST out of the right subsequence [4, 5, 6, 7], and then combine them together (i.e. cartesian product). The tricky part is that we could consider the number of unique BST out of sequence [1,2] as G(2), and the number of of unique BST out of sequence [4, 5, 6, 7] as G(4). Therefore, F(3,7) = G(2) * G(4). i.e. F(i, n) = G(i-1) * G(n-i) 1 <= i <= n Combining the above two formulas, we obtain the recursive formula for G(n). i.e. G(n) = G(0) * G(n-1) + G(1) * G(n-2) + ... + G(n-1) * G(0) In terms of calculation, we need to start with the lower number, since the value of G(n) depends on the values of G(0) ... G(n-1). With the above explanation and formulas, here is the implementation in Java. public int numTrees(int n) { int [] G = new int[n+1]; G[0] = G[1] = 1; for(int i=2; i<=n; ++i) { for(int j=1; j<=i; ++j) { G[i] += G[j-1] * G[i-j]; } } return G[n]; }
Given n, how many structurally unique BST's (binary search trees) that store values 1 ... n? Example: Input: 3 Output: 5 Explanation: Given n = 3, there are a total of 5 unique BST's: 1 3 3 2 1 \ / / / \ \ 3 2 1 1 3 2 / / \ \ 2 1 2 3
The basic idea is here: Say we have 2 arrays, PRE and IN. Preorder traversing implies that PRE[0] is the root node. Then we can find this PRE[0] in IN, say it's IN[5]. Now we know that IN[5] is root, so we know that IN[0] - IN[4] is on the left side, IN[6] to the end is on the right side. Recursively doing this on subarrays, we can build a tree out of it :) Hope this helps. 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) { if (preStart > preorder.length - 1 || inStart > inEnd) { return null; } TreeNode root = new TreeNode(preorder[preStart]); int inIndex = 0; // Index of current root in inorder for (int i = inStart; i <= inEnd; i++) { if (inorder[i] == root.val) { inIndex = i; } } root.left = helper(preStart + 1, inStart, inIndex - 1, preorder, inorder); root.right = helper(preStart + inIndex - inStart + 1, inIndex + 1, inEnd, preorder, inorder); return root; }
Given preorder and inorder traversal of a tree, construct the binary tree. Note: You may assume that duplicates do not exist in the tree. For example, given preorder = [3,9,20,15,7] inorder = [9,3,15,20,7] Return the following binary tree: 3 / \ 9 20 / \ 15 7
public int divide(int dividend, int divisor) { if(dividend == 0) return 0; if(divisor == 0) return Integer.MAX_VALUE; if(dividend == divisor) return 1; int sign = 1; if(dividend < 0 || divisor < 0) sign = -1; dividend = Math.abs(dividend); divisor = Math.abs(divisor); int target = 0; while(divisor <= dividend) { dividend = dividend - divisor; target++; } return sign < 0 ? negate(target) : target; } private int negate(int i) { return 0 - i; }
Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator. Return the quotient after dividing dividend by divisor. The integer division should truncate toward zero. Example 1: Input: dividend = 10, divisor = 3 Output: 3 Example 2: Input: dividend = 7, divisor = -3 Output: -2
Generic approach for backtracking public List<List<Integer>> combine(int n, int k) { List<List<Integer>> result = new ArrayList<>(); backtrack(result, new ArrayList<>(), 1, n, k); return result; } private void backtrack(List<List<Integer>> result, List<Integer> tempList, int start, int n, int k) { if(tempList.size() > k) { return; } else if(tempList.size() == k) { result.add(new ArrayList<>(tempList)); } else { for(int i=start; i <= n; i++) { tempList.add(i); backtrack(result, tempList, i + 1, n, k); tempList.remove(tempList.size() - 1); } } }
Given two integers n and k, return all possible combinations of k numbers out of 1 ... n. Example: Input: n = 4, k = 2 Output: [ [2,4], [3,4], [2,3], [1,2], [1,3], [1,4], ]
Start from right to left, perform multiplication on every pair of digits, and add them together. Let's draw the process! From the following draft, we can immediately conclude: `num1[i] * num2[j]` will be placed at indices `[i + j`, `i + j + 1]` public String multiply(String num1, String num2) { int m = num1.length(), n = num2.length(); int[] pos = new int[m + n]; for(int i = m - 1; i >= 0; i--) { for(int j = n - 1; j >= 0; j--) { int mul = (num1.charAt(i) - '0') * (num2.charAt(j) - '0'); int p1 = i + j, p2 = i + j + 1; int sum = mul + pos[p2]; pos[p1] += sum / 10; pos[p2] = (sum) % 10; } } StringBuilder sb = new StringBuilder(); for(int p : pos) if(!(sb.length() == 0 && p == 0)) sb.append(p); return sb.length() == 0 ? "0" : sb.toString(); }
Given two non-negative integers num1 and num2 represented as strings, return the product of num1 and num2, also represented as a string. Example 1: Input: num1 = "2", num2 = "3" Output: "6" Example 2: Input: num1 = "123", num2 = "456" Output: "56088" Note: The length of both num1 and num2 is < 110. Both num1 and num2 contain only digits 0-9. Both num1 and num2 do not contain any leading zero, except the number 0 itself. You must not use any built-in BigInteger library or convert the inputs to integer directly.
public static int ladderLength(String s1, String s2, Set<String> dict) { Queue<WordNode> toExplore = new LinkedList<>(); toExplore.add(new WordNode(s1, 1)); dict.add(s2); while(!toExplore.isEmpty()) { WordNode curr = toExplore.poll(); if(curr.word.equals(s2)) { return curr.numSteps; } char[] arr = curr.word.toCharArray(); for(int i = 0; i < arr.length; i++) { for(char c = 'a'; c <= 'z'; c++) { char tmp = arr[i]; if(arr[i] != c) { arr[i] = c; } String tmpStr = new String(arr); if(dict.contains(tmpStr)) { toExplore.add(new WordNode(tmpStr, curr.numSteps + 1)); dict.remove(tmpStr); } arr[i] = tmp; } } } return 0; }
Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that: Only one letter can be changed at a time. Each transformed word must exist in the word list. Note that beginWord is not a transformed word. Note: Return 0 if there is no such transformation sequence. All words have the same length. All words contain only lowercase alphabetic characters. You may assume no duplicates in the word list. You may assume beginWord and endWord are non-empty and are not the same. Example 1: Input: beginWord = "hit", endWord = "cog", wordList = ["hot","dot","dog","lot","log","cog"] Output: 5 Explanation: As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog", return its length 5.
public int calculate(String s) { int len = s.length(); if(s == null || len == 0) return 0; Stack<Integer> stack = new Stack<Integer>(); int num = 0; char sign = '+'; for(int i = 0; i < len; i++){ if(Character.isDigit(s.charAt(i))){ num = num * 10 + (s.charAt(i) - '0'); } if((!Character.isDigit(s.charAt(i)) && ' ' != s.charAt(i)) || i == len-1) { if(sign == '-'){ stack.push(-num); } if(sign == '+'){ stack.push(num); } if(sign == '*'){ stack.push(stack.pop() * num); } if(sign == '/'){ stack.push(stack.pop() / num); } sign = s.charAt(i); num = 0; } } int result = 0; for(int i : stack){ result += i; } return result; }
Implement a basic calculator to evaluate a simple expression string. The expression string contains only non-negative integers, +, -, *, / operators and empty spaces . The integer division should truncate toward zero. Example 1: Input: "3+2*2" Output: 7
class Trie { private class TrieNode { Map<Character, TrieNode> children; boolean endOfWord; public TrieNode() { children = new HashMap<>(); endOfWord = false; } } private TrieNode root; /** Initialize your data structure here. */ public Trie() { this.root = new TrieNode(); } /** Inserts a word into the trie. */ public void insert(String word) { TrieNode current = root; for (int i = 0; i < word.length(); i++) { char c = word.charAt(i); TrieNode node = current.children.get(c); if(node == null) { node = new TrieNode(); current.children.put(c, node); } current = node; } current.endOfWord = true; } /** Returns if the word is in the trie. */ public boolean search(String word) { TrieNode current = root; for(int i = 0; i < word.length(); i++) { char c = word.charAt(i); TrieNode node = current.children.get(c); if(node == null) { return false; } current = node; } return current.endOfWord; } /** Returns if there is any word in the trie that starts with the given prefix. */ public boolean startsWith(String prefix) { TrieNode current = root; for(int i = 0; i < prefix.length(); i++) { char c = prefix.charAt(i); TrieNode node = current.children.get(c); if(node == null) { return false; } current = node; } return true; } } /** * Your Trie object will be instantiated and called as such: * Trie obj = new Trie(); * obj.insert(word); * boolean param_2 = obj.search(word); * boolean param_3 = obj.startsWith(prefix); */
Implement a trie with insert, search, and startsWith methods. Example: Trie trie = new Trie(); trie.insert("apple"); trie.search("apple"); // returns true trie.search("app"); // returns false trie.startsWith("app"); // returns true trie.insert("app"); trie.search("app"); // returns true
public class BSTIterator { private Queue<Integer> queue; public BSTIterator(TreeNode root) { queue = new LinkedList<>(); inOrder(root); } private void inOrder(TreeNode root) { if(root == null) return; inOrder(root.left); queue.add(root.val); inOrder(root.right); } /** @return whether we have a next smallest number */ public boolean hasNext() { return queue.size() > 0; } /** @return the next smallest number */ public int next() { return queue.poll(); } }
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. Note: next() and hasNext() should run in average O(1) time and uses O(h) memory, where h is the height of the tree.
public void nextPermutation(int[] nums) { int i = nums.length - 2; while (i >= 0 && nums[i + 1] <= nums[i]) { i--; } if (i >= 0) { int j = nums.length - 1; while (j >= 0 && nums[j] <= nums[i]) { j--; } swap(nums, i, j); } reverse(nums, i + 1); } private void reverse(int[] nums, int start) { int i = start, j = nums.length - 1; while (i < j) { swap(nums, i, j); i++; j--; } } private void swap(int[] nums, int i, int j) { int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; }
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers. If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order). The replacement must be in-place and use only constant extra memory. Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column. 1,2,3 → 1,3,2 3,2,1 → 1,2,3 1,1,5 → 1,5,1
In a binary tree, if we consider null as leaves, then all non-null node provides 2 outdegree and 1 indegree (2 children and 1 parent), except root all null node provides 0 outdegree and 1 indegree (0 child and 1 parent). Suppose we try to build this tree. During building, we record the difference between out degree and in degree diff = outdegree - indegree. When the next node comes, we then decrease diff by 1, because the node provides an in degree. If the node is not null, we increase diff by 2, because it provides two out degrees. If a serialization is correct, diff should never be negative and diff will be zero when finished. public boolean isValidSerialization(String preorder) { String[] nodes = preorder.split(","); int diff = 1; for (String node: nodes) { // decrement indegree node by one diff--; if (diff < 0) return false; // increment outdegree node by two if (!node.equals("#")) diff += 2; } return diff == 0; } video: https://www.youtube.com/watch?v=_mbnPPHJmTQ
One way to serialize a binary tree is to use pre-order traversal. When we encounter a non-null node, we record the node's value. If it is a null node, we record using a sentinel value such as #. _9_ / \ 3 2 / \ / \ 4 1 # 6 / \ / \ / \ # # # # # # For example, the above binary tree can be serialized to the string "9,3,4,#,#,1,#,#,2,#,6,#,#", where # represents a null node. Given a string of comma separated values, verify whether it is a correct preorder traversal serialization of a binary tree. Find an algorithm without reconstructing the tree. Each comma separated value in the string must be either an integer or a character '#' representing null pointer. You may assume that the input format is always valid, for example it could never contain two consecutive commas such as "1,,3". Example 1: Input: "9,3,4,#,#,1,#,#,2,#,6,#,#" Output: true Example 2: Input: "1,#" Output: false
public class Solution { private int[] original; private int[] copy; public Solution(int[] nums) { original = new int[nums.length]; copy = new int[nums.length]; for(int i = 0; i < nums.length; i++) { original[i] = nums[i]; copy[i] = nums[i]; } } /** Resets the array to its original configuration and return it. */ public int[] reset() { for(int i = 0; i < original.length; i++) copy[i] = original[i]; return copy; } /** Returns a random shuffling of the array. */ public int[] shuffle() { int N = copy.length; for(int i = 0; i < N; i++) { int r = i + (int) (Math.random() * (N - i)); int tmp = copy[r]; copy[r] = copy[i]; copy[i] = tmp; } return copy; } }
Shuffle a set of numbers without duplicates. Example: // Init an array with set 1, 2, and 3. int[] nums = {1,2,3}; Solution solution = new Solution(nums); // Shuffle the array [1,2,3] and return its result. Any permutation of [1,2,3] must equally likely to be returned. solution.shuffle(); // Resets the array back to its original configuration [1,2,3]. solution.reset(); // Returns the random shuffling of array [1,2,3]. solution.shuffle();
public int lengthLongestPath(String input) { Deque<Integer> stack = new ArrayDeque<>(); String[] arr = input.split("\n"); int maxLen = 0; stack.push(0); //dummy null length for (String s: arr) { /* numOfTabs is the number of "\t", numOfTabs = 0 when "\t" is not found, because s.lastIndexOf("\t") returns -1. So normally, the first parent "dir" have numOfTabs 0. */ int numOfTabs = s.lastIndexOf("\t") + 1; /* Level is defined as numOfTabs + 1. For example, in "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext", dir is level 1, subdir1 and subdir2 are level 2, file.ext is level3 */ level = numOfTabs + 1; /* The following part of code is the case that we want to consider when there are several subdirectories in a same level. We want to remove the path length of the directory or the file of same level that we added during previous step, and calculate the path length of current directory or file that we are currently looking at. */ while (level < stack.size()) stack.poll(); int curLen = stack.peek() + s.length() - numOfTabs + 1; stack.push(curLen); if (s.contains(".")) maxLen = Math.max(maxLen, curLen - 1); //Only update the maxLen when a file is discovered, // And remove the "/" at the end of file } return maxLen; }
Suppose we abstract our file system by a string in the following manner: The string "dir\n\tsubdir1\n\tsubdir2\n\t\tfile.ext" represents: dir subdir1 subdir2 file.ext The directory dir contains an empty sub-directory subdir1 and a sub-directory subdir2 containing a file file.ext. The string "dir\n\tsubdir1\n\t\tfile1.ext\n\t\tsubsubdir1\n\tsubdir2\n\t\tsubsubdir2\n\t\t\tfile2.ext" represents: dir subdir1 file1.ext subsubdir1 subdir2 subsubdir2 file2.ext The directory dir contains two sub-directories subdir1 and subdir2. subdir1 contains a file file1.ext and an empty second-level sub-directory subsubdir1. subdir2 contains a second-level sub-directory subsubdir2 containing a file file2.ext. We are interested in finding the longest (number of characters) absolute path to a file within our file system. For example, in the second example above, the longest absolute path is "dir/subdir2/subsubdir2/file2.ext", and its length is 32 (not including the double quotes). Given a string representing the file system in the above format, return the length of the longest absolute path to file in the abstracted file system. If there is no file in the system, return 0. Note: The name of a file contains at least a . and an extension. The name of a directory or sub-directory will not contain a .. Time complexity required: O(n) where n is the size of the input string. Notice that a/aa/aaa/file1.txt is not the longest file path, if there is another path aaaaaaaaaaaaaaaaaaaaa/sth.png.
public int[][] reconstructQueue(int[][] people) { if(people.length==0 || people[0].length==0) return people; PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[0] == o2[0] ? o1[1] - o2[1] : o2[0] - o1[0]); for (int[] person : people) { pq.offer(person); } List<int[]> list = new ArrayList<>(); while (!pq.isEmpty()) { int[] person = pq.poll(); list.add(person[1], person); } return list.toArray(new int[people.length][people[0].length]); }
Suppose you have a random list of people standing in a queue. Each person is described by a pair of integers (h, k), where h is the height of the person and k is the number of people in front of this person who have a height greater than or equal to h. Write an algorithm to reconstruct the queue. Note: The number of people is less than 1,100. Example Input: [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]] Output: [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
public int rob(TreeNode root) { return Math.max(rob(root, true), rob(root, false)); } private int rob(TreeNode node, boolean canRob){ if(node == null) return 0; if (node.left == null && node.right == null) return canRob ? node.val : 0; if(canRob) return node.val + rob(node.left, false) + rob(node.right, false); else return Math.max(rob(node.left, true), rob(node.left, false)) + Math.max(rob(node.right, true), rob(node.right, false)); }
The thief has found himself a new place for his thievery again. There is only one entrance to this area, called the "root." Besides the root, each house has one and only one parent house. After a tour, the smart thief realized that "all houses in this place forms a binary tree". It will automatically contact the police if two directly-linked houses were broken into on the same night. Determine the maximum amount of money the thief can rob tonight without alerting the police. Example 1: Input: [3,2,3,null,3,null,1] 3 / \ 2 3 \ \ 3 1 Output: 7 Explanation: Maximum amount of money the thief can rob = 3 + 3 + 1 = 7.
public int canCompleteCircuit(int[] gas, int[] cost) { int start = 0; int total = 0; int tank = 0; //if car fails at 'start', record the next station for(int i = 0; i < gas.length; i++) { tank = tank + gas[i] - cost[i]; if(tank < 0) { start = i+1; total += tank; tank = 0; } } return (total + tank < 0) ? -1 : start; }
There are N gas stations along a circular route, where the amount of gas at station i is gas[i]. You have a car with an unlimited gas tank and it costs cost[i] of gas to travel from station i to its next station (i+1). You begin the journey with an empty tank at one of the gas stations. Return the starting gas station's index if you can travel around the circuit once in the clockwise direction, otherwise return -1. Note: If there exists a solution, it is guaranteed to be unique. Both input arrays are non-empty and have the same length. Each element in the input arrays is a non-negative integer. Example 1: Input: gas = [1,2,3,4,5] cost = [3,4,5,1,2] Output: 3 Explanation: Start at station 3 (index 3) and fill up with 4 unit of gas. Your tank = 0 + 4 = 4 Travel to station 4. Your tank = 4 - 1 + 5 = 8 Travel to station 0. Your tank = 8 - 2 + 1 = 7 Travel to station 1. Your tank = 7 - 3 + 2 = 6 Travel to station 2. Your tank = 6 - 4 + 3 = 5 Travel to station 3. The cost is 5. Your gas is just enough to travel back to station 3. Therefore, return 3 as the starting index.
public boolean canFinish(int numCourses, int[][] prerequisites) { List<List<Integer>> adjList = new ArrayList<>(); for(int i = 0; i < numCourses; i++) { adjList.add(i, new ArrayList<>()); } for(int[] pre : prerequisites) { adjList.get(pre[1]).add(pre[0]); } int[] visited = new int[numCourses]; // reuse so that each node visited once // must check every node. eg.[1,0],[0,1] for(int i = 0; i < numCourses; i++) { if(dfs(adjList, i, visited)) return false; } return true; } // Check if back edge (directed cycle) exists. If not => DAG => able to topological sort private boolean dfs(List<List<Integer>> adjList, int v, int[] visited) { visited[v] = 1; for(Integer nb : adjList.get(v)) { // visited and nb is v's ancestor => back edge if(visited[nb] == 1) return true; // nb is not visited => tree edge if(visited[nb] == 0 && dfs(adjList, nb, visited)) return true; } visited[v] = 2; return false; }
There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] Given the total number of courses and a list of prerequisite pairs, is it possible for you to finish all courses? Example 1: Input: 2, [[1,0]] Output: true Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible.
public int[] findOrder(int numCourses, int[][] prerequisites) { if(prerequisites == null){ throw new IllegalArgumentException("illegal prerequisites array"); } int len = prerequisites.length; //if there is no prerequisites, return a sequence of courses if(len == 0){ int[] res = new int[numCourses]; for(int m=0; m<numCourses; m++){ res[m]=m; } return res; } //records the number of prerequisites each course (0,...,numCourses-1) requires int[] pCounter = new int[numCourses]; for(int i=0; i<len; i++){ pCounter[prerequisites[i][0]]++; } //stores courses that have no prerequisites Queue<Integer> queue = new LinkedList<Integer>(); for(int i=0; i<numCourses; i++){ if(pCounter[i]==0){ queue.add(i); } } int numNoPre = queue.size(); //initialize result int[] result = new int[numCourses]; int j=0; while(!queue.isEmpty()){ int c = queue.remove(); result[j++]=c; for(int i=0; i<len; i++){ if(prerequisites[i][1]==c){ pCounter[prerequisites[i][0]]--; if(pCounter[prerequisites[i][0]]==0){ queue.add(prerequisites[i][0]); numNoPre++; } } } } //return result if(numNoPre==numCourses){ return result; }else{ return new int[0]; } }
There are a total of n courses you have to take, labeled from 0 to n-1. Some courses may have prerequisites, for example to take course 0 you have to first take course 1, which is expressed as a pair: [0,1] Given the total number of courses and a list of prerequisite pairs, return the ordering of courses you should take to finish all courses. There may be multiple correct orders, you just need to return one of them. If it is impossible to finish all courses, return an empty array. Example 1: Input: 2, [[1,0]] Output: [0,1] Explanation: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So the correct course order is [0,1] .
public boolean searchMatrix(int[][] matrix, int target) { // always test for edge cases if(matrix.length == 0 || matrix[0].length == 0) return false; for(int i = 0; i < matrix.length; i++) { int n = matrix[i].length; if(target <= matrix[i][n - 1]) { int result = binarySearch(matrix[i], target); if(result >= 0) return true; } } return false; } public int binarySearch(int[] arr, int target) { int lo = 0; int hi = arr.length - 1; while(lo <= hi) { int mid = lo + (hi - lo) / 2; if(target > arr[mid]) { lo = mid + 1; } else if(target < arr[mid]) { hi = mid - 1; } else return mid; } return -1; }
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: Input: matrix = [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] target = 3 Output: true
We start search the matrix from top right corner, initialize the current position to top right corner, if the target is greater than the value in current position, then the target can not be in entire row of current position because the row is sorted, if the target is less than the value in current position, then the target can not in the entire column because the column is sorted too. We can rule out one row or one column each time, so the time complexity is O(m+n). public class Solution { public boolean searchMatrix(int[][] matrix, int target) { if(matrix == null || matrix.length < 1 || matrix[0].length <1) { return false; } int col = matrix[0].length-1; int row = 0; while(col >= 0 && row <= matrix.length-1) { if(target == matrix[row][col]) { return true; } else if(target < matrix[row][col]) { col--; } else if(target > matrix[row][col]) { row++; } } return false; } }
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, 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.
// O(n) solution, since there is no recursion at all public int rob(int[] nums) { if (nums == null || nums.length == 0) return 0; int n = nums.length; if (n == 1) { return nums[0]; } return Math.max(robHelper(nums, 0, n - 2), robHelper(nums, 1, n - 1)); } private int robHelper(int[] nums, int start, int end) { int curr, prev, prev2; curr = prev = prev2 = 0; for (int i = start; i <= end; i++) { curr = Math.max(prev2 + nums[i], prev); prev2 = prev; prev = curr; } return curr; }
You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have security system connected and it will automatically contact the police if two adjacent houses were broken into on the same night. Given a list of non-negative integers representing the amount of money of each house, determine the maximum amount of money you can rob tonight without alerting the police. Example 1: Input: [2,3,2] Output: 3 Explanation: You cannot rob house 1 (money = 2) and then rob house 3 (money = 2), because they are adjacent houses.
public Node flatten(Node head) { if(head == null || (head.next == null && head.child == null)) { return head; } Stack<Node> stack = new Stack<>(); stack.push(head); Node prev = null; while(!stack.isEmpty()) { Node curr = stack.pop(); if(prev == null) { prev = curr; } else { prev.next = curr; curr.prev = prev; prev = curr; } if(curr.next != null) { stack.push(curr.next); } if(curr.child != null) { stack.push(curr.child); } curr.child = null; } return head; }
You are given a doubly linked list which in addition to the next and previous pointers, it could have a child pointer, which may or may not point to a separate doubly linked list. These child lists may have one or more children of their own, and so on, to produce a multilevel data structure, as shown in the example below. Flatten the list so that all the nodes appear in a single-level, doubly linked list. You are given the head of the first level of the list. Example: Input: 1---2---3---4---5---6--NULL | 7---8---9---10--NULL | 11--12--NULL Output: 1-2-3-7-8-11-12-9-10-4-5-6-NULL
public void rotate(int[][] matrix) { int len = matrix.length; rotateHelper(matrix, 0, len-1); } public void rotateHelper(int[][] matrix, int j, int n) { if(j > n/2) return; for(int i = j; i < n-j; i++) { int tmp = matrix[j][i]; matrix[j][i] = matrix[n-i][j]; matrix[n-i][j] = matrix[n-j][n-i]; matrix[n-j][n-i] = matrix[i][n-j]; matrix[i][n-j] = tmp; } rotate_helper(matrix, j+1, n); }
You are given an n x n 2D matrix representing an image. Rotate the image by 90 degrees (clockwise). Note: You have to rotate the image in-place, which means you have to modify the input 2D matrix directly. DO NOT allocate another 2D matrix and do the rotation. Example 1: Given input matrix = [ [1,2,3], [4,5,6], [7,8,9] ], rotate the input matrix in-place such that it becomes: [ [7,4,1], [8,5,2], [9,6,3] ]
public List<Integer> rightSideView(TreeNode root) { List<Integer> res = new ArrayList<>(); helper(root,0,res); return res; } void helper(TreeNode rt, int h, List<Integer> res){ if(rt == null) return; if(h >= res.size()) res.add(rt.val); helper(rt.right, h+1,res); helper(rt.left, h+1,res); }
Given a binary tree, imagine yourself standing on the right side of it, return the values of the nodes you can see ordered from top to bottom. Example: Input: [1,2,3,null,5,null,4] Output: [1, 3, 4] Explanation: 1 <--- / \ 2 3 <--- \ \ 5 4 <---
private ListNode node; public TreeNode sortedListToBST(ListNode head) { if(head == null){ return null; } int size = 0; ListNode runner = head; node = head; while(runner != null){ runner = runner.next; size ++; } return inorderHelper(0, size - 1); } public TreeNode inorderHelper(int start, int end){ if(start > end){ return null; } int mid = start + (end - start) / 2; TreeNode left = inorderHelper(start, mid - 1); TreeNode treenode = new TreeNode(node.val); treenode.left = left; node = node.next; TreeNode right = inorderHelper(mid + 1, end); treenode.right = right; return treenode; }
Given a singly linked list where elements are sorted in ascending order, convert it to a height balanced BST. For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1. Example: Given the sorted linked list: [-10,-3,0,5,9], One possible answer is: [0,-3,9,-10,null,5], which represents the following height balanced BST: 0 / \ -3 9 / / -10 5
public static List<String> letterCombinations(String digits) { String digitletter[] = {"","","abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"}; List<String> result = new ArrayList<String>(); if (digits.length()==0) return result; result.add(""); for (int i=0; i<digits.length(); i++) result = combine(digitletter[digits.charAt(i)-'0'],result); return result; } public static List<String> combine(String digit, List<String> l) { List<String> result = new ArrayList<String>(); for (int i=0; i<digit.length(); i++) for (String x : l) result.add(x+digit.charAt(i)); return result; }
Given a string containing digits from 2-9 inclusive, return all possible letter combinations that the number could represent. A mapping of digit to letters (just like on the telephone buttons) is given below. Note that 1 does not map to any letters. Example: Input: "23" Output: ["ad", "ae", "af", "bd", "be", "bf", "cd", "ce", "cf"].
public String convert(String s, int nRows) { char[] c = s.toCharArray(); int len = c.length; StringBuffer[] sb = new StringBuffer[nRows]; for (int i = 0; i < sb.length; i++) sb[i] = new StringBuffer(); int i = 0; while (i < len) { for (int idx = 0; idx < nRows && i < len; idx++) // vertically down sb[idx].append(c[i++]); for (int idx = nRows-2; idx >= 1 && i < len; idx--) // obliquely up sb[idx].append(c[i++]); } for (int idx = 1; idx < sb.length; idx++) sb[0].append(sb[idx]); return sb[0].toString(); }
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) 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: string convert(string s, int numRows); Example 1: Input: s = "PAYPALISHIRING", numRows = 3 Output: "PAHNAPLSIIGYIR" Example 2: Input: s = "PAYPALISHIRING", numRows = 4 Output: "PINALSIGYAHRPI" Explanation: P I N A L S I G Y A H R P I
public RandomListNode copyRandomList(RandomListNode head) { if(head == null) return null; Map<RandomListNode, RandomListNode> map = new HashMap<>(); RandomListNode curr = head; while(curr != null) { map.put(curr, new RandomListNode(curr.label)); curr = curr.next; } for(Map.Entry<RandomListNode, RandomListNode> entry : map.entrySet()) { RandomListNode tmp = entry.getValue(); tmp.next = map.get(entry.getKey().next); tmp.random = map.get(entry.getKey().random); } return map.get(head); }
A linked list is given such that each node contains an additional random pointer which could point to any node in the list or null. Return a deep copy of the list.
public List<List<Integer>> combinationSum3(int k, int n) { if (k == 0 || n < 1) { return new ArrayList<>(); } List<List<Integer>> ans = new ArrayList<>(); int[] nums = {1, 2, 3, 4, 5, 6, 7, 8, 9}; helper(k, n, ans, new ArrayList<>(), 0, 0, nums); return ans; } public void helper(int k, int n, List<List<Integer>> ans, List<Integer> list, int sum, int pos, int[] nums) { if (sum > n) { return; } if (list.size() == k) { if (sum == n) { ans.add(new ArrayList<>(list)); } return; } for (int i = pos; i < nums.length; i++) { sum += nums[i]; list.add(nums[i]); helper(k, n, ans, list, sum, i + 1, nums); sum -= nums[i]; list.remove(list.size() - 1); } }
Find all possible combinations of k numbers that add up to a number n, given that only numbers from 1 to 9 can be used and each combination should be a unique set of numbers. Note: All numbers will be positive integers. The solution set must not contain duplicate combinations. Example 1: Input: k = 3, n = 7 Output: [[1,2,4]] Example 2: Input: k = 3, n = 9 Output: [[1,2,6], [1,3,5], [2,3,4]]
public static int atoi(String number) { boolean minus = false; int result = 0; for (int i = 0; i < number.length(); i++) { if(number.charAt(i) == '-') { minus = true; continue; } result = result * 10 + (number.charAt(i) - '0'); } return minus ? -1 * result : result; }
Implement atoi which converts a string to an integer. The function first discards as many whitespace characters as necessary until the first non-whitespace character is found. Then, starting from this character, takes an optional initial plus or minus sign followed by as many numerical digits as possible, and interprets them as a numerical value. The string can contain additional characters after those that form the integral number, which are ignored and have no effect on the behavior of this function. If the first sequence of non-whitespace characters in str is not a valid integral number, or if no such sequence exists because either str is empty or it contains only whitespace characters, no conversion is performed. If no valid conversion could be performed, a zero value is returned.
public String intToRoman(int num) { if (num < 1 || num >=4000){ return ""; } String[] M = {"", "M", "MM", "MMM"}; String[] C = {"", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM"}; String[] X = {"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC"}; String[] I = {"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"}; StringBuilder result = new StringBuilder(); result.append(M[num/1000]); result.append(C[(num%1000)/100]); result.append(X[(num%100)/10]); result.append(I[num%10]); return result.toString(); }
Roman numerals are represented by seven different symbols: I, V, X, L, C, D and M. Symbol Value I 1 V 5 X 10 L 50 C 100 D 500 M 1000 For example, two is written as II in Roman numeral, just two one's added together. Twelve is written as, XII, which is simply X + II. The number twenty seven is written as XXVII, which is XX + V + II. Roman numerals are usually written largest to smallest from left to right. However, the numeral for four is not IIII. Instead, the number four is written as IV. Because the one is before the five we subtract it making four. The same principle applies to the number nine, which is written as IX. There are six instances where subtraction is used: I can be placed before V (5) and X (10) to make 4 and 9. X can be placed before L (50) and C (100) to make 40 and 90. C can be placed before D (500) and M (1000) to make 400 and 900. Given an integer, convert it to a roman numeral. Input is guaranteed to be within the range from 1 to 3999. Example 1: Input: 3 Output: "III"
public int findMin(int[] nums) { int lo = 0; int hi = nums.length - 1; while(lo < hi - 1) { int mid = lo + (hi - lo) / 2; if(nums[mid] > nums[hi]) { lo = mid; } else { hi = mid; } } return Math.min(nums[lo], nums[hi]); }
Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]). Find the minimum element. You may assume no duplicate exists in the array. Example 1: Input: [3,4,5,1,2] Output: 1 Example 2: Input: [4,5,6,7,0,1,2] Output: 0
public String getPermutation(int n, int k) { List<Integer> list = new LinkedList<Integer>(); StringBuilder s = new StringBuilder(); int[] factorial = new int[n+1]; int index = 0; factorial[0] = 1; for(int i = 1; i <= n; i++) { list.add(i); factorial[i] = factorial[i - 1] * i; } for(int i = n; i >= 1; i--) { index = (k - 1) % factorial[i] / factorial[i - 1]; s.append(list.get(index)); list.remove(index); } return s.toString(); }
The set [1,2,3,...,n] contains a total of n! unique permutations. By listing and labeling all of the permutations in order, we get the following sequence for n = 3: "123" "132" "213" "231" "312" "321" Given n and k, return the kth permutation sequence. Note: Given n will be between 1 and 9 inclusive. Given k will be between 1 and n! inclusive. Example 1: Input: n = 3, k = 3 Output: "213"
public int nthUglyNumber(int n) { if(n==1) return 1; PriorityQueue<Long> q = new PriorityQueue(); q.add(1l); for(long i=1; i<n; i++) { long tmp = q.poll(); while(!q.isEmpty() && q.peek()==tmp) tmp = q.poll(); q.add(tmp*2); q.add(tmp*3); q.add(tmp*5); } return q.poll().intValue(); }
Write a program to find the n-th ugly number. Ugly numbers are positive numbers whose prime factors only include 2, 3, 5. Example: Input: n = 10 Output: 12 Explanation: 1, 2, 3, 4, 5, 6, 8, 9, 10, 12 is the sequence of the first 10 ugly numbers. Note: 1 is typically treated as an ugly number. n does not exceed 1690.
public ListNode addTwoNumbers(ListNode l1, ListNode l2) { int carry = 0; int sum = l1.val + l2.val; if(sum >= 10) { carry = 1; sum = sum % 10; } ListNode node = new ListNode(sum); ListNode head = node; l1 = l1.next; l2 = l2.next; addNext(l1, l2, node, carry); return head; } void addNext(ListNode l1, ListNode l2, ListNode node, int carry) { if(l1 == null && l2 == null) { if(carry != 0) { node.next = new ListNode(carry); } return; } int val = carry; if(l1 != null) { val += l1.val; } if(l2 != null) { val += l2.val; } if(val >= 10) { carry = 1; val = val % 10; } else { carry = 0; } node.next = new ListNode(val); addNext(l1 == null ? null: l1.next, l2 == null ? null : l2.next, node.next, carry); }
You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order and each of their nodes contain a single digit. Add the two numbers and return it as a linked list. You may assume the two numbers do not contain any leading zero, except the number 0 itself. Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8 Explanation: 342 + 465 = 807.
public ListNode swapPairs(ListNode head) { ListNode dummy = new ListNode(0); dummy.next = head; ListNode current = dummy; while (current.next != null && current.next.next != null) { ListNode first = current.next; ListNode second = current.next.next; first.next = second.next; current.next = second; current.next.next = first; current = current.next.next; } return dummy.next; }
Given a linked list, swap every two adjacent nodes and return its head. Example: Given 1->2->3->4, you should return the list as 2->1->4->3.
public ListNode deleteDuplicates(ListNode head) { if(head == null) return null; ListNode result = new ListNode(0); result.next = head; ListNode pre = result; ListNode cur = head; while(cur != null){ while(cur.next != null && cur.val == cur.next.val){ cur = cur.next; } if(pre.next == cur){ pre = pre.next; } else{ pre.next = cur.next; } cur = cur.next; } return result.next; }
Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. Example 1: Input: 1->2->3->3->4->4->5 Output: 1->2->5
The basic idea of the following solution is merging adjacent lands, and the merging should be done recursively. Each element is visited once only. So time is O(m*n). public int numIslands(char[][] grid) { if(grid==null || grid.length==0||grid[0].length==0) return 0; int m = grid.length; int n = grid[0].length; int count=0; for(int i=0; i<m; i++){ for(int j=0; j<n; j++){ if(grid[i][j]=='1'){ count++; merge(grid, i, j); } } } return count; } public void merge(char[][] grid, int i, int j){ int m=grid.length; int n=grid[0].length; if(i<0||i>=m||j<0||j>=n||grid[i][j]!='1') return; grid[i][j]='X'; merge(grid, i-1, j); merge(grid, i+1, j); merge(grid, i, j-1); merge(grid, i, j+1); }
Given a 2d grid map of '1's (land) and '0's (water), count 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. Example 1: Input: 11110 11010 11000 00000 Output: 1