Sum of Two integers
Given two integers a and b, return the sum of the two integers without using the operators + and -.add bit by bit, be mindful of carry, after adding, if carry is still 1, then add it as well
while(b != 0){
int carry = a & b;
a = a ^ b;
b = carry << 1; //if we have a carry value, we add it again.
}
return a;Number of 1 bits
Write a function that takes an unsigned integer and returns the number of '1' bits it has (also known as the Hamming weight).modulo, and dividing n; mod and div are expensive, to divide use bit shift, instead of mod to get 1's place use bitwise & 1;
public static int hammingWeight(int n) {
int ones = 0;
while(n!=0) {
ones = ones + (n & 1);
n = n>>>1;
}
return ones;Counting Bits
Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n), ans[i] is the number of 1's in the binary representation of i.write out result for num=16 to figure out pattern; res[i] = res[i - offset], where offset is the biggest power of 2 <= I;
public int[] countBits(int num) { int[] f = new int[num + 1];
for (int i=1; i<=num; i++) f[i] = f[i >> 1] + (i & 1);
return f; }
https://leetcode.com/problems/counting-bits/discuss/79539/Three-Line-Java-SolutionMissing Number
Given an array nums containing n distinct numbers in the range [0, n], return the only number in the range that is missing from the array.compute expected sum - real sum; xor n with each index and value;
public int missingNumber(int[] nums) {
int xor = 0, i = 0;
for (i = 0; i < nums.length; i++) {
xor = xor ^ i ^ nums[i];
}
return xor ^ i; }Reverse Bits
Reverse bits of a given 32 bits unsigned integer.reverse each of 32 bits;
public int reverseBits(int n) {
if (n == 0) return 0;
int result = 0;
for (int i = 0; i < 32; i++) {
result <<= 1;
if ((n & 1) == 1) result++;
n >>= 1; }
return result; }Climbing Stairs (DP)
You are climbing a staircase. It takes n steps to reach the top.
Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?subproblem find (n-1) and (n-2), sum = n;
public int climbStairs(int n) {
// base cases
if(n <= 0) return 0;
if(n == 1) return 1;
if(n == 2) return 2;
int one_step_before = 2;
int two_steps_before = 1;
int all_ways = 0;
for(int i=2; i<n; i++){
all_ways = one_step_before + two_steps_before; two_steps_before = one_step_before; one_step_before = all_ways;
}
return all_ways; }Coin Change (DP)
You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.
Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.top-down: recursive dfs, for amount, branch for each coin, cache to store prev coin_count for each amount; bottom-up: compute coins for amount = 1, up until n, using for each coin (amount - coin), cache prev values
public int coinChange(int[] coins, int amount) {
if(amount<0) return -1;
if(amount==0) return 0;
int cc=-1;
for(int i=0;i<coins.length;i++) {
int coin=coinChange(coins, amount-coins[i]);
if(coin>=0) cc=cc<0?coin+1:Math.min(cc,coin+1);
}
return cc; }Longest Increasing Subsequence
Given an integer array nums, return the length of the longest strictly increasing subsequence.recursive: foreach num, get subseq with num and without num, only include num if prev was less, cache solution of each; dp=subseq length which must end with each num, curr num must be after a prev dp or by itself;
public class Solution {
public int lengthOfLIS(int[] nums) {
int[] dp = new int[nums.length];
int len = 0;
for(int x : nums) {
int i = Arrays.binarySearch(dp, 0, len, x);
if(i < 0) i = -(i + 1);
dp[i] = x;
if(i == len) len++; }
return len; } }Longest Common Subsequence (DP)
Given two strings text1 and text2, return the length of their longest common subsequence. If there is no common subsequence, return 0.
"ace" is a subsequence of "abcde".recursive: if first chars are equal find lcs of remaining of each, else max of: lcs of first and remain of 2nd and lcs of 2nd remain of first, cache result; nested forloop to compute the cache without recursion;
class Solution { public int longestCommonSubsequence(String text1, String text2) {
char[] chars1 = text1.toCharArray();
char[] chars2 = text2.toCharArray();
int[][] dp = new int[chars1.length + 1][chars2.length + 1];
for (int i = 0; i < chars1.length; i++) {
for (int j = 0; j < chars2.length; j++)
dp[i+1][j+1] = chars1[i] == chars2[j]? dp[i][j] + 1 : Math.max(dp[i][j+1], dp[i+1][j]);
}
return dp[chars1.length][chars2.length]; } }Word Break problem
Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words.for each prefix, if prefix is in dict and wordbreak(remaining str)=True, then return True, cache result of wordbreak;
public boolean wordBreak(String s, Set<String> dict) {
if (s == null || s.length() == 0) return false;
int n = s.length();
// dp[i] represents whether s[0...i] can be formed by dict
boolean[] dp = new boolean[n];
for (int i = 0; i < n; i++) {
for (int j = 0; j <= i; j++) {
String sub = s.substring(j, i + 1);
if (dict.contains(sub) && (j == 0 || dp[j - 1])) {
dp[i] = true; break; }
}
}
return dp[n - 1]; }Combination Sum
Given an array of distinct integers candidates and a target integer target, return a list of all unique combinations of candidates where the chosen numbers sum to target. You may return the combinations in any order.
The same number may be chosen from candidates an unlimited number of times. Two combinations are unique if the frequency of at least one of the chosen numbers is different.
It is guaranteed that the number of unique combinations that sum up to target is less than 150 combinations for the given input.visualize the decision tree, base case is curSum = or > target, each candidate can have children of itself or elements to right of it inorder to elim duplicate solutions;
https://leetcode.com/problems/combination-sum/discuss/16509/Iterative-Java-DP-solutionHouse Robber
Each house has a certain amount of money stashed, the only constraint stopping you from robbing each of them is that adjacent houses have security systems connected and it will automatically contact the police if two adjacent houses were broken into on the same night.for each num, get max of prev subarr, or num + prev subarr not including last element, store results of prev, and prev not including last element
https://leetcode.com/problems/house-robber/discuss/55681/Java-O(n)-solution-space-O(1)House Robber 2
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 a security system connected, and it will automatically contact the police if two adjacent houses were broken into on the same night.subarr = arr without first & last, get max of subarr, then pick which of first/last should be added to it
class Solution {
public:
int rob(vector<int>& nums) {
int n = nums.size();
if (n < 2) return n ? nums[0] : 0; return max(robber(nums, 0, n - 2), robber(nums, 1, n - 1));
}
private:
int robber(vector<int>& nums, int l, int r) {
int pre = 0, cur = 0;
for (int i = l; i <= r; i++) {
int temp = max(pre + nums[i], cur); pre = cur; cur = temp; }
return cur; } };Decode Ways
A message containing letters from A-Z can be encoded into numbers using the following mapping:
'A' -> "1" 'B' -> "2" ... 'Z' -> "26"
To decode an encoded message, all the digits must be grouped then mapped back into letters using the reverse of the mapping above (there may be multiple ways).can cur char be decoded in one or two ways? Recursion -> cache -> iterative dp solution, a lot of edge cases to determine, 52, 31, 29, 10, 20 only decoded one way, 11, 26 decoded two ways
https://leetcode.com/problems/decode-ways/discuss/30358/Java-clean-DP-solution-with-explanationUnique Paths
There is a robot on an m x n grid. The robot is initially located at the top-left corner (i.e., grid[0][0]). The robot tries to move to the bottom-right corner (i.e., grid[m - 1][n - 1]). The robot can only move either down or right at any point in time.
Given the two integers m and n, return the number of possible unique paths that the robot can take to reach the bottom-right corner.work backwards from solution, store paths for each position in grid, to further optimize, we don't store whole grid, only need to store prev row;
public class Solution {
public int uniquePaths(int m, int n) {
if(m == 1 || n == 1) return 1;
m--;
n--;
if(m < n) {
// Swap, so that m is the bigger number
m = m + n;
n = m - n; m = m - n; } long res = 1; int j = 1; for(int i = m+1; i <= m+n; i++, j++){ // Instead of taking factorial, keep on multiply & divide res *= i; res /= j; } return (int)res; } }Jump Game
You are given an integer array nums. You are initially positioned at the array's first index, and each element in the array represents your maximum jump length at that position.visualize the recursive tree, cache solution for O(n) time/mem complexity, iterative is O(1) mem, just iterate backwards to see if element can reach goal node, if yes, then set it equal to goal node, continue;
bool canJump(vector<int>& nums) {
int n = nums.size();
vector<bool> jump(n,false);
jump[n-1]=true;
for(int i=n-2;i>=0;i--) {
for(int j=0;j<=nums[i] && i+j<n;j++) {
if(jump[i+j]==true) { jump[i]=true; break; }
}
}
return jump[0]; }Clone Graph
Given a reference of a node in a connected undirected graph.
Return a deep copy (clone) of the graph.
Each node in the graph contains a value (int) and a list (List[Node]) of its neighbors.
class Node { public int val; public List<Node> neighbors; }recursive dfs, hashmap for visited nodes
https://leetcode.com/problems/clone-graph/discuss/42309/Depth-First-Simple-Java-SolutionCourse Schedule
There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai.
For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1.
Return true if you can finish all courses. Otherwise, return false.build adjacency_list with edges, run dfs on each V, if while dfs on V we see V again, then loop exists, otherwise V isnt in a loop, 3 states= not visited, visited, still visiting
https://leetcode.com/problems/course-schedule/discuss/58516/Easy-BFS-Topological-sort-JavaPacific Atlantic Water Flow
https://leetcode.com/problems/pacific-atlantic-water-flow/dfs each cell, keep track of visited, and track which reach pac, atl; dfs on cells adjacent to pac, atl, find overlap of cells that are visited by both pac and atl cells;
https://leetcode.com/problems/pacific-atlantic-water-flow/discuss/90733/Java-BFS-and-DFS-from-OceanNumber of Islands
Given an m x n 2D binary grid grid which represents a map of '1's (land) and '0's (water), return the number of islands.
An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.foreach cell, if cell is 1 and unvisited run dfs, increment cound and marking each contigous 1 as visited.
https://leetcode.com/problems/number-of-islands/discuss/56359/Very-concise-Java-AC-solutionLongest Consecutive Sequence
Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence.
You must write an algorithm that runs in O(n) time.use bruteforce and try to optimize, consider the max subseq containing each num; add each num to hashset, for each num if num-1 doesn't exist, count the consecutive nums after num, ie num+1; there is also a union-find solution;
public int longestConsecutive(int[] nums) {
if(nums == null || nums.length == 0) return 0;
Set<Integer> set = new HashSet<>();
for(int i : nums) set.add(i);
int ans = 0; for(int num : nums) {
int left = num - 1;
int right = num + 1;
while(set.remove(left)) left--;
while(set.remove(right)) right++;
ans = Math.max(ans,right - left - 1);
if(set.isEmpty()) return ans; //save time if there are items in nums, but no item in hashset. }
return ans; }Number of Connected Components in an Undirected Graph
You have a graph of n nodes. You are given an integer n and an array edges where edges[i] = [ai, bi] indicates that there is an edge between ai and bi in the graph.
Return the number of connected components in the graph.dfs on each node that hasn't been visited, increment component count, adjacency list; bfs and union find are possible;
https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/discuss/77574/Easiest-2ms-Java-SolutionInsert Interval
https://leetcode.com/problems/insert-interval/insert new interval in order, then merge intervals; newinterval could only merge with one interval that comes before it, then add remaining intervals;
https://leetcode.com/problems/insert-interval/discuss/21602/Short-and-straight-forward-Java-solutionMerge Intervals
Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, and return an array of the non-overlapping intervals that cover all the intervals in the input.sort each interval, overlapping intervals should be adjacent, iterate and build solution; also graph method, less efficient, more complicated
https://leetcode.com/problems/merge-intervals/discuss/21222/A-simple-Java-solution