7,Dynamic Programming
1,Unique Paths
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).
Analyse:
public class Solution { public int uniquePaths(int m, int n) { int[][] dp = new int[m][n]; for (int i = 0; i < n; i++) { dp[0][i] = 1; } for (int i = 0; i < m; i++) { dp[i][0] = 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]; } }
滚动指针来优化空间复杂度:
public class Solution { public int uniquePaths(int m, int n) { int[][] dp = new int[2][n]; for (int i = 0; i < n; i++) { dp[0][i] = 1; } dp[0][0] = 1; for (int i = 1; i < m; i++) { dp[i % 2][0] = 1; for (int j = 1; j < n; j++) { dp[i % 2][j] = dp[(i - 1) % 2][j] + dp[i % 2][j - 1]; } } return dp[(m - 1) % 2][n - 1]; } }
1--follow up :有障碍物。
public class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { if (obstacleGrid == null || obstacleGrid.length == 0) { return 0; } int m = obstacleGrid.length; int n = obstacleGrid[0].length; int[][] dp = new int[m][n]; // initialize for (int i = 0; i < m; i++) { if (obstacleGrid[i][0] != 1) { dp[i][0] = 1; } else { break; } } for (int j = 0; j < n; j++) { if (obstacleGrid[0][j] != 1) { dp[0][j] = 1; } else { break; } } // calculate 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]; } }
滚动数组优化:
public class Solution { public int uniquePathsWithObstacles(int[][] obstacleGrid) { if (obstacleGrid == null || obstacleGrid.length == 0) { return 0; } int m = obstacleGrid.length; int n = obstacleGrid[0].length; int[][] dp = new int[2][n]; for (int j = 0; j < n; j++) { if (obstacleGrid[0][j] != 1) { dp[0][j] = 1; } else { break; } } // calculate for (int i = 1; i < m; i++) { if (dp[(i - 1) % 2][0] != 0 && obstacleGrid[i][0] != 1) { dp[i % 2][0] = 1; } else { dp[i % 2][0] = 0; } for (int j = 1; j < n; j++) { if (obstacleGrid[i][j] != 1) { dp[i % 2][j] = dp[(i - 1) % 2][j] + dp[i % 2][j - 1]; } else { dp[i % 2][j] = 0; } } } return dp[(m - 1) % 2][n - 1]; } }
2,Minimum Path Sum
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.
Analyse:
public class Solution { public int minPathSum(int[][] grid) { if (grid == null || grid.length == 0) { return 0; } int m = grid.length; int n = grid[0].length; int[][] dp = new int[2][n]; dp[0][0] = grid[0][0]; // for (int i = 1; i < m; i++) { // dp[i][0] = dp[i - 1][0] + grid[i][0]; // } for (int j = 1; j < n; j++) { dp[0][j] = dp[0][j - 1] + grid[0][j]; } for (int i = 1; i < m; i++) { dp[i % 2][0] = dp[(i - 1) % 2][0] + grid[i][0]; for (int j = 1; j < n; j++) { dp[i % 2][j] = Math.min(dp[(i - 1) % 2][j], dp[i % 2][j - 1]) + grid[i][j]; } } return dp[(m - 1) % 2][n - 1]; } }
3,climb stairs
You are climbing a stair case. It takes n steps to reach to the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top? Subscribe to see which companies asked this question
Analyse:
public class Solution { public int climbStairs(int n) { if (n <= 0) { return 0; } if (n <= 2) { return n; } int[] dp = new int[2]; dp[0] = 1; dp[1] = 2; for (int i = 2; i < n; i++) { dp[i % 2] = dp[(i - 1) % 2] + dp[(i - 2) % 2]; } return dp[(n - 1) % 2]; } }
4,maximum subarray
public class Solution { public int maxSubArray(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int[] dp = new int[2]; int max = nums[0]; dp[0] = nums[0]; for (int i = 1; i < nums.length; i++) { dp[i % 2] = Math.max(dp[(i - 1) % 2] + nums[i], nums[i]); max = Math.max(max, dp[i % 2]); } return max; } }
5,triangle
public class Solution { public int minimumTotal(List> triangle) { if (triangle == null || triangle.size() == 0) { return 0; } int size = triangle.size(); for (int i = size - 2; i >= 0; i--) { // find the min for (int j = 0; j <= i; j++) { triangle.get(i).set(j, triangle.get(i).get(j) + Math.min(triangle.get(i + 1).get(j), triangle.get(i + 1).get(j + 1))); } } return triangle.get(0).get(0); } }
6,best time to buy and sell stock
public class Solution { public int maxProfit(int[] prices) { if (prices == null || prices.length == 0) { return 0; } int minPrice = prices[0]; int maxProfit = 0; for (int i = 1; i < prices.length; i++) { minPrice = Math.min(minPrice, prices[i]); maxProfit = Math.max(maxProfit, prices[i] - minPrice); } return maxProfit; } }
7,
6,Recursion
1,climb building (print all the possible ways)
Analyse:
public class Solution { public static void main(String[] args) { climb(3, ""); } public static void climb(int n, String preWay) { if (n == 1) { System.out.println(preWay + " 1"); return; } if (n == 2) { System.out.println(preWay + " 2"); System.out.println(preWay + " 1 1"); return; } String preWay1 = preWay + " 1"; climb(n - 1, preWay1); String preWay2 = preWay + " 2"; climb(n - 2, preWay2); } }
2,Hanoi
Analyse : Move the first (n - 1) disk from A to B; then move the nth disk from A to C; move the other (n - 1) disk from b to c.
(1) how many steps we need to move all n disks from A to C.
import java.io.*; class test { public static void main (String[] args) { System.out.println(hanoiSteps(3)); } public static int hanoiSteps(int n) { if (n == 1) { return 1; } return hanoiSteps(n - 1) + 1 + hanoiSteps(n - 1); } }
(2) Print all the steps that is needed to move all n disks from A to C.
import java.io.*; class test { public static void hanoi(int n, char source, char spare, char target) { if (n == 1) { System.out.println("Move " + source + " to " + target); return; } hanoi(n - 1, source, target, spare); System.out.println("Move " + source + " to " + target); hanoi(n - 1, spare, source, target); } }
(3) 0-1 knapsack
Given a knapsack which can hold s pounds of items, and a set of items with weight w1, w2, ... wn. Return whether we can pick specific items so that their total weight s.
Analyse: pick it: (s - w[i], w - w[i]), or not pick it : (s, w - w[i]);
import java.io.*; class test { public static void main(String[] args) { int[] weights = {14, 8, 7, 5, 3}; System.out.println(knapsack(20, weights, 0)); } public static boolean knapsack(int s, int[] weights, int index) { if (s == 0) { return true; } if (s < 0 || index >= weights.length) { return false; } return knapsack(s - weights[index], weights, index + 1) || knapsack(s, weights, index + 1); } }
(4)0-1 knapsack
0-1 Knapsack II Given a knapsack which can hold s pounds of items, and a set of items with weight w1, w2, ... wn. Try to put items into the pack as many as possible, return the largest weight we can get in the knapsack.
Analyse : pick it weights[index] + knapsack2, index + 1; not pick it : knapsack2, index + 1;
public class Solution { public int getMax(int s, int[] weights) { return knapsack2(s, weights, 0); } public static int knapsack2(int s, int[] weights, int index) { if (s == 0 || index == weights.length) { return 0; } if (weights[index] > s) { return knapsack2(s, weights, index + 1); } return Math.max(knapsack2(s, weights, index + 1), weights[index] + knapsack2(s - weights[index], weights, index + 1)); } }
(5) knapsack III
Knapsack III
Given a set of candidate numbers (C) and a target number (T), find all unique
combinations in C where the candidate numbers sums to T.
All candidate numbers are unique.
The same repeated number may be chosen from C unlimited number of times.
Analyse :
import java.util.ArrayList; import java.util.Arrays; public class Solution { public ArrayList> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); ArrayList > results = new ArrayList >(); ArrayList cur = new ArrayList (); combine(candidates, 0, target, results, cur); return results; } public void combine(int[] candidates, int index, int target, ArrayList > results, ArrayList cur) { if (target < 0) { return; } if (target == 0) { results.add(new ArrayList (cur)); return; } for (int i = index; i < candidates.length; i++) { cur.add(candidates[i]); combine(candidates, i, target-candidates[i], results, cur); cur.remove(cur.size()-1); } return; } }
(6) knapsack III-2
Given a collection of candidate numbers (C) and a target number (T), find all
unique combinations in C where the candidate numbers sums to T.
Candidate numbers may contain duplicate.
Each number in C may only be used once in the combination.
import java.util.ArrayList; import java.util.Arrays; public class Solution { public ArrayList> combinationSum(int[] candidates, int target) { Arrays.sort(candidates); ArrayList > results = new ArrayList >(); ArrayList cur = new ArrayList (); combine(candidates, 0, target, results, cur); return results; } public void combine(int[] candidates, int index, int target, ArrayList > results, ArrayList cur) { if (target < 0) { return; } if (target == 0) { results.add(new ArrayList (cur)); return; } for (int i = index; i < candidates.length; i++) { cur.add(candidates[i]); combine(candidates, i + 1, target-candidates[i], results, cur); cur.remove(cur.size()-1); while (i < candidates.length - 1 && candidates[i] == candidates[i + 1]) { i++; } } return; } }
(7) maze
Maze Given a maze and a start point and a target point, return whether the target can be reached. Example Input: Start Point: (0, 0); Target Point (5, 5); Maze: char[][] = { {'.', 'X', '.', '.', '.', 'X'}, {'.', '.', '.', 'X', '.', 'X'}, {'X', 'X', '.', 'X', '.', '.'}, {'.', 'X', 'X', 'X', '.', 'X'}, {'.', '.', '.', '.', '.', 'X'}, {'.', '.', '.', '.', '.', '.'} } Example Output: True
Analyse:bfs
1,return whether the target can be reached
public class Solution { public static void main(String[] args) { char[][] maze= { {'.', 'X', '.', '.', '.', 'X'}, {'.', '.', '.', 'X', '.', 'X'}, {'X', 'X', '.', 'X', '.', '.'}, {'.', 'X', 'X', 'X', '.', 'X'}, {'.', '.', '.', '.', '.', 'X'}, {'.', '.', '.', '.', '.', '.'} }; System.out.println(solveMaze(maze, 0, 0, 5, 5)); } public static boolean solveMaze(char[][] maze, int startX, int startY, int targetX, int targetY) { if (startX == targetX && startY == targetY) { return true; } maze[startX][startY] = 'X'; int[] dx = {1, 0, -1, 0}; int[] dy = {0, 1, 0, -1}; for (int i = 0; i < 4; i++) { int newX = startX + dx[i]; int newY = startY + dy[i]; if (newX < 0 || newX >= maze.length || newY < 0 || newY >= maze[0].length || maze[newX][newY] == 'X') { continue; } if (solveMaze(maze, newX, newY, targetX, targetY)){ return true; } } return false; } }
2,print out the path to reach the target.
import java.util.ArrayList; import java.util.Arrays; public class Solution { public static void main(String[] args) { ArrayListlist = new ArrayList(); char[][] maze= { {'.', 'X', '.', '.', '.', 'X'}, {'.', '.', '.', 'X', '.', 'X'}, {'X', 'X', '.', 'X', '.', '.'}, {'.', 'X', 'X', 'X', '.', 'X'}, {'.', '.', '.', '.', '.', 'X'}, {'.', '.', '.', '.', '.', '.'} }; System.out.println(solveMaze(maze, 0, 0, 5, 5, list)); System.out.println(list); } public static boolean solveMaze(char[][] maze, int startX, int startY, int targetX, int targetY, ArrayList path) { if (startX == targetX && startY == targetY) { return true; } maze[startX][startY] = 'X'; int[] dx = {1, 0, -1, 0}; int[] dy = {0, 1, 0, -1}; char[] direction = {'R', 'U', 'L', 'D'}; for (int i = 0; i < 4; i++) { int newX = startX + dx[i]; int newY = startY + dy[i]; path.add(direction[i]); if (newX < 0 || newX >= maze.length || newY < 0 || newY >= maze[0].length || maze[newX][newY] == 'X') { continue; } if (solveMaze(maze, newX, newY, targetX, targetY, path)){ return true; } path.remove(path.size() - 1); } return false; } }
(8) generate parentheses
22. Generate Parentheses QuestionEditorial Solution My Submissions Total Accepted: 96789 Total Submissions: 251907 Difficulty: Medium 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: [ "((()))", "(()())", "(())()", "()(())", "()()()" ]
Analyse: use left and right to remeber the leaved numbers of left parenthesis and right parenthesis. left == 0 && right == 0, put the string into list.
public class Solution { public ListgenerateParenthesis(int n) { List results = new ArrayList(); generateParenthesis(results, "", n, n); return results; } public static void generateParenthesis(List results, String prefix, int left, int right) { if (left == 0 && right == 0) { results.add(prefix); return; } if (left > 0) { generateParenthesis(results, prefix + "(", left - 1, right); } if (left < right) { generateParenthesis(results, prefix + ")", left, right - 1); } } }
(9) permutation
46. Permutations QuestionEditorial Solution My Submissions Total Accepted: 109331 Total Submissions: 294780 Difficulty: Medium Given a collection of distinct numbers, return all possible permutations. For example, [1,2,3] have the following permutations: [ [1,2,3], [1,3,2], [2,1,3], [2,3,1], [3,1,2], [3,2,1] ]
Analyse:
public class Solution { public List> permute(int[] nums) { List
> results = new ArrayList(); List
listNow = new ArrayList(); results.add(listNow); if (nums == null || nums.length == 0) { return results; } for (int i = 0; i < nums.length; ++i) { List > temp = new ArrayList(); for (List
list : results) { int size = list.size(); for (int j = 0; j <= size; ++j) { List cur = new ArrayList(list); cur.add(j, nums[i]); temp.add(cur); } } results = new ArrayList(temp); } return results; } }
(10) permutation II
47. Permutations II QuestionEditorial Solution My Submissions Total Accepted: 78186 Total Submissions: 271215 Difficulty: Medium Given a collection of numbers that might contain duplicates, return all possible unique permutations. For example, [1,1,2] have the following unique permutations: [ [1,1,2], [1,2,1], [2,1,1] ]
Analyse: contains
public class Solution { public static List> permuteUnique(int[] nums) { List
> results = new ArrayList(); List
listNow = new ArrayList(); results.add(listNow); if (nums == null || nums.length == 0) { return results; } for (int i = 0; i < nums.length; ++i) { List > temp = new ArrayList(); for (List
list : results) { int size = list.size(); for (int j = 0; j <= size; ++j) { List cur = new ArrayList(list); cur.add(j, nums[i]); if (!temp.contains(cur)) { temp.add(cur); } } } results = new ArrayList(temp); } return results; } }
(11)subsets
78. Subsets QuestionEditorial Solution My Submissions Total Accepted: 104901 Total Submissions: 320125 Difficulty: Medium Given a set of distinct integers, nums, return all possible subsets. Note: The solution set must not contain duplicate subsets. For example, If nums = [1,2,3], a solution is: [ [3], [1], [2], [1,2,3], [1,3], [2,3], [1,2], [] ]
Analyse:
public class Solution { public List> subsets(int[] nums) { List
> results = new ArrayList(); List
list = new ArrayList(); results.add(list); if (nums == null || nums.length == 0) { return results; } for (int i = 0; i < nums.length; ++i) { List > temp = new ArrayList(results); for (List
now : results) { List listTemp= new ArrayList(now); listTemp.add(nums[i]); temp.add(listTemp); } results = new ArrayList(temp); } return results; } }
(12)find all the largest weight's combination
Given a knapsack which can hold s pounds of items, and a set of items with
weight w1, w2, ... wn. Try to put items into the pack as many as possible, print out
all the items that can get the largest weight. Each item can only get picked once.
Analyse: first, find the largest weights, then find the combination.
import java.util.ArrayList; import java.util.Arrays; public class Solution { public ArrayList> knapsackPrint(int s, int[] weights) { // get the largest weight int max = getMax(s, weights); ArrayList > results = new ArrayList(); results = combinationSum(weights, max); System.out.println(results); return results; } public static int getMax(int s, int[] weights) { return knapsackMax(s, weights, 0); } public static int knapsackMax(int s, int[] weights, int index) { if (s == 0 || index == weights.length) { return 0; } if (weights[index] > s) { return knapsackMax(s, weights, index + 1); } return Math.max(knapsackMax(s, weights, index + 1), weights[index] + knapsackMax(s - weights[index], weights, index + 1)); } public static ArrayList > combinationSum(int[] candidates, int target) { Arrays.sort(candidates); ArrayList > results = new ArrayList >(); ArrayList cur = new ArrayList (); combine(candidates, 0, target, results, cur); return results; } public static void combine(int[] candidates, int index, int target, ArrayList > results, ArrayList cur) { if (target < 0) { return; } if (target == 0) { results.add(new ArrayList (cur)); return; } for (int i = index; i < candidates.length; i++) { cur.add(candidates[i]); combine(candidates, i + 1, target-candidates[i], results, cur); cur.remove(cur.size()-1); while (i < candidates.length - 1 && candidates[i] == candidates[i + 1]) { i++; } } return; } }
5,Stack & Queue
(1)implement stack
class Stack{ private int top; int capacity; T[] stack; public Stack(int inCapacity) { capacity = inCapacity; stack = (T[]) new Object[capacity]; top = -1; } public int size() { return top + 1; } public void push(T value) { if (top + 1 == capacity) { throw new IllegalStateException("Stack is full"); } else { stack[++top] = value; } } public T peek() { if (top == -1) { throw new IllegalStateException("Stack is empty"); } else { return stack[top]; } } public T pop() { if (top == -1) { throw new IllegalStateException("Stack is empty"); } else { return stack[top--]; } } }
(2) implement queue use array
class Queue{ private int front; private int rear; int capacity; int size; T[] queue; public Queue(int inCapacity) { capacity = inCapacity; queue = (T[]) new Object[capacity]; front = 0; rear = 0; size = 0; } public int size() { return size; } public void add(T value) { if (size == capacity) { throw new IllegalStateException("Queue is full"); } else { queue[rear] = value; rear = (rear + 1) % capacity; size++; } } public T remove() { T value = null; if (size == 0) { throw new IllegalStateException("Queue is empty, can't remove"); } else { value = queue[front]; front = (front + 1) % capacity; size--; } return value; } }
(3)min stack
155. Min Stack My Submissions QuestionEditorial Solution Total Accepted: 77918 Total Submissions: 337784 Difficulty: Easy Design a stack that supports push, pop, top, and retrieving the minimum element in constant time. push(x) -- Push element x onto stack. pop() -- Removes the element on top of the stack. top() -- Get the top element. getMin() -- Retrieve the minimum element in the stack. Example: MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> Returns -3. minStack.pop(); minStack.top(); --> Returns 0. minStack.getMin(); --> Returns -2.
Analyse : two stack
public class MinStack { Stackstack; Stack minStack; /** initialize your data structure here. */ public MinStack() { stack = new Stack(); minStack = new Stack(); } public void push(int x) { stack.push(x); if (minStack.isEmpty()) { minStack.push(x); } else { if (x < minStack.peek()) { minStack.push(x); } else { minStack.push(minStack.peek()); } } } public void pop() { stack.pop(); minStack.pop(); } public int top() { return stack.peek(); } public int getMin() { return minStack.peek(); } } /** * Your MinStack object will be instantiated and called as such: * MinStack obj = new MinStack(); * obj.push(x); * obj.pop(); * int param_3 = obj.top(); * int param_4 = obj.getMin(); */
(4)max stack
public class MaxStack { Stackstack; Stack maxStack; /** initialize your data structure here. */ public MaxStack() { stack = new Stack(); maxStack = new Stack(); } public void push(int x) { stack.push(x); if (maxStack.isEmpty()) { maxStack.push(x); } else { if (x > maxStack.peek()) { maxStack.push(x); } else { maxStack.push(maxStack.peek()); } } } public void pop() { stack.pop(); maxStack.pop(); } public int top() { return stack.peek(); } public int getMax() { return maxStack.peek(); } }
(5)valid parentheses
20. Valid Parentheses My Submissions QuestionEditorial Solution Total Accepted: 115251 Total Submissions: 384811 Difficulty: Easy Given a string containing just the characters '(', ')', '{', '}', '[' and ']', determine if the input string is valid. The brackets must close in the correct order, "()" and "()[]{}" are all valid but "(]" and "([)]" are not.
Analyse : two error
public class Solution { public boolean isValid(String s) { if (s == null || s.length() == 0) { return true; } Stackstack = new Stack(); for (int i = 0; i < s.length(); ++i) { char c = s.charAt(i); if (c == '(' || c == '[' || c == '{') { stack.push(c); } else { if (stack.isEmpty()) { // Error 1 return false; } char pre = stack.pop(); if (c == ')') { if ( pre != '(') { return false; } } else if (c == ']') { if (pre != '[') { return false; } } else { if (pre != '{') { return false; } } } } if (stack.isEmpty()) { //Error 2 return true; } return false; } }
(6)implement queue usint stacks
232. Implement Queue using Stacks My Submissions QuestionEditorial Solution Total Accepted: 47988 Total Submissions: 140316 Difficulty: Easy Implement the following operations of a queue using stacks. push(x) -- Push element x to the back of queue. pop() -- Removes the element from in front of queue. peek() -- Get the front element. empty() -- Return whether the queue is empty. Notes: You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid. Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack. You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).
Analyse: two stack
class MyQueue { // Push element x to the back of queue. Stackstack1 = new Stack(); Stack stack2 = new Stack(); public void push(int x) { stack1.push(x); } // Removes the element from in front of queue. public void pop() { if (stack2.isEmpty()) { while (!stack1.isEmpty()) { stack2.add(stack1.pop()); } } stack2.pop(); } // Get the front element. public int peek() { if (stack2.isEmpty()) { while (!stack1.isEmpty()) { stack2.add(stack1.pop()); } } // Error: stack2.pop(); return stack2.peek(); } // Return whether the queue is empty. public boolean empty() { if (stack1.isEmpty() && stack2.isEmpty()) { return true; } return false; } }
(6) implement stack use queues
225. Implement Stack using Queues My Submissions QuestionEditorial Solution Total Accepted: 43270 Total Submissions: 140856 Difficulty: Easy Implement the following operations of a stack using queues. push(x) -- Push element x onto stack. pop() -- Removes the element on top of the stack. top() -- Get the top element. empty() -- Return whether the stack is empty. Notes: You must use only standard operations of a queue -- which means only push to back, peek/pop from front, size, and is empty operations are valid. Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue. You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack).
Analyse : use two queues, keep one of them is empty. push x into the queues which is empty, and them push all
elements of another queue into it. when you want to pop , you just poll the queue's top element which is not empty.
class MyStack { Queuequeue1 = new LinkedList(); Queue queue2 = new LinkedList(); // Push element x onto stack. public void push(int x) { if (queue1.isEmpty()) { queue1.add(x); while (!queue2.isEmpty()) { queue1.add(queue2.poll()); } } else { queue2.add(x); while (!queue1.isEmpty()) { queue2.add(queue1.poll()); } } } // Removes the element on top of the stack. public void pop() { if (!queue1.isEmpty()) { queue1.poll(); } else { queue2.poll(); } } // Get the top element. public int top() { if (!queue1.isEmpty()) { return queue1.peek(); } else { return queue2.peek(); } } // Return whether the stack is empty. public boolean empty() { return queue1.isEmpty() && queue2.isEmpty(); } }
(7) cows facing right
= = - Cows facing right --> = = = = - = = = = = = = = = 1 2 3 4 5 6 Copyright © ???? http://www.zhitongguigu.com All the cows are facing right, and they can only see other cows in front of it and shorter than itself. It can be blocked by other taller cows. Example: 6 2 3 1 7 4 Output: 5
Analyse:
import java.util.Stack; public class Solution { public static int seeCows(int[] cow) { int result = 0; Stackstack = new Stack(); for (int i = 0; i < cow.length; ++i) { if (stack.isEmpty() || stack.peek() > cow[i]) { stack.push(cow[i]); } else { while (!stack.isEmpty() && stack.peek() <= cow[i]) { stack.pop(); result += stack.size(); } } } while(!stack.isEmpty()) { stack.pop(); result += stack.size(); } return result; } }
(8) longest rectangle in histogram
84. Largest Rectangle in Histogram My Submissions QuestionEditorial Solution Total Accepted: 62886 Total Submissions: 256370 Difficulty: Hard Given n non-negative integers representing the histogram's bar height where the width of each bar is 1, find the area of largest rectangle in the histogram. Above is a histogram where width of each bar is 1, given height = [2,1,5,6,2,3]. The largest rectangle is shown in the shaded area, which has area = 10 unit. For example, Given heights = [2,1,5,6,2,3], return 10.
Analyse:
public class Solution { public int largestRectangleArea(int[] heights) { if (heights == null || heights.length == 0) { return 0; } int area = 0; Stackstack = new Stack(); for (int i = 0; i < heights.length; ++i) { if (stack.isEmpty() || heights[i] > heights[stack.peek()]) { stack.push(i); } else { int start = stack.pop(); int width = stack.isEmpty() ? i : i - stack.peek() - 1; area = Math.max(area, heights[start] * width); i--; } } while (!stack.isEmpty()) { int start = stack.pop(); int width = stack.isEmpty() ? heights.length : heights.length - 1 - stack.peek(); area = Math.max(area, heights[start] * width); } return area; } }
(9)NQueens
Eight Queens The eight queens puzzle is the problem of placing eight chess queens on an 8×8 chessboard so that no two queens threaten each other.
Analyse: board[i] = j : in the row, put the queen on the j column.
package solution; import java.util.ArrayList; import java.util.List; public class Solution { public static void main(String[] args) { List> result = solveNQueens(8); System.out.println(result.size()); System.out.println("here"); System.out.println(result); } public static List
> solveNQueens(int n) { List
> results = new ArrayList(); int[] board = new int[n]; putQueens(board, 0, results); return results; } public static void putQueens(int[] board, int row, List
> results) { if (row == board.length) { saveResult(board, results); return; } for (int col = 0; col < board.length; ++col) { if (isLegal(board, row, col)) { board[row] = col; putQueens(board, row + 1, results); } } } public static boolean isLegal(int[] board, int row, int col) { for (int i = row - 1; i >= 0; i--) { if (board[i] == col || Math.abs(board[i] - col) == row - i) { return false; } } return true; } public static void saveResult(int[] board, List
> results) { List
result = new ArrayList<>(); for (int i = 0; i < board.length; i++) { StringBuffer oneLine = new StringBuffer(); for (int j = 0; j < board.length; j++) { if (j == board[i]) { oneLine.append('Q'); } else { oneLine.append('.'); } } result.add(oneLine.toString()); } results.add(result); } }
---------------------------------------------------------------------------------------------------
4,linkedlist
(1)implement the LinkedList
class ListNode { ListNode head; ListNode next; int val; ListNode(int x) { val = x; } } public class LinkedList { private static ListNode head = null; private static int length = 0; public static boolean checkBoundsExclusive(int index) { if (index < 0 || index >= length) { System.out.println("ArrayIndexOutOfBoundException"); return true; } else { return false; } } public static ListNode getEntry(int index) { if (!checkBoundsExclusive(index)) { ListNode cur = head; for (int i = 0; i < index; i++) { cur = cur.next; } return cur; } else { return null; } } public static void set(int index, int value) { if (!checkBoundsExclusive(index)) { ListNode node = getEntry(index); node.val = value; } } public static void add(int index, int value) { if (!checkBoundsExclusive(index)) { ListNode newNode = new ListNode(value); if (index == 0) { newNode.next = head; head = newNode; return; } ListNode pre = getEntry(index - 1); ListNode next = pre.next; pre.next = newNode; pre.next.next = next; } } public static void remove(int index) { if (!checkBoundsExclusive(index)) { if (index == 0) { head = head.next; } ListNode pre = getEntry(index - 1); pre.next = pre.next.next; } } }
(2) remove nth node from end of list
19. Remove Nth Node From End of List My Submissions QuestionEditorial Solution Total Accepted: 115441 Total Submissions: 383623 Difficulty: Easy Given a linked list, remove the nth node from the end of list and return its head. For 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. Note: Given n will always be valid. Try to do this in one pass.
Analyse: find its pre-pointer.
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode removeNthFromEnd(ListNode head, int n) { if (head == null || n <= 0) { return null; } ListNode dummy = new ListNode(-1); dummy.next = head; ListNode first = dummy; for (int i = 0; i < n; i++) { if (first == null) { return head; } first = first.next; } ListNode second = dummy; while (first.next != null) { second = second.next; first = first.next; } second.next = second.next.next; return dummy.next; } }
(3)middle of linked list
Middle of Linked List Description Notes Testcase Judge Find the middle node of a linked list. Have you met this question in a real interview? Yes Example Given 1->2->3, return the node with value 2. Given 1->2, return the node with value 1.
Analyse : fast != null && fast.next != null && fast.next.next != null
/** * Definition for ListNode * public class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { /** * @param head: the head of linked list. * @return: a middle node of the linked list */ public ListNode middleNode(ListNode head) { // Write your code here if (null == head) { return head; } ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; } return slow; } }
(4)Linked List Cycle
141. Linked List Cycle My Submissions QuestionEditorial Solution Total Accepted: 113091 Total Submissions: 309422 Difficulty: Easy Given a linked list, determine if it has a cycle in it. Follow up: Can you solve it without using extra space?
Analyse: fast, slow pointer
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public boolean hasCycle(ListNode head) { if (head == null || head.next == null) { return false; } ListNode slow = head; ListNode fast = head; while (fast != null && fast.next != null && fast.next.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) { return true; } } return false; } }
(5) Linked List Cycle II
142. Linked List Cycle II My Submissions QuestionEditorial Solution Total Accepted: 79077 Total Submissions: 253054 Difficulty: Medium Given a linked list, return the node where the cycle begins. If there is no cycle, return null. Note: Do not modify the linked list. Follow up: Can you solve it without using extra space?
Analyse :
/** * Definition for singly-linked list. * class ListNode { * int val; * ListNode next; * ListNode(int x) { * val = x; * next = null; * } * } */ public class Solution { public ListNode detectCycle(ListNode head) { if (null == head || head.next == null) { return null; } ListNode slow = head; ListNode fast = head; boolean flag = false; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) { flag = true; break; // forget this, so TLE } } if (!flag) { return null; } slow = head; while (fast != slow) { fast = fast.next; slow = slow.next; } return slow; } } /** * [1] tail connects to node index 0 */
(6)remove duplicate from sorted list
Analyse:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode deleteDuplicates(ListNode head) { if (null == head) { return head; } ListNode pre = head; while (pre != null && pre.next != null) { if (pre.val == pre.next.val) { pre.next = pre.next.next; } else { pre = pre.next; } } return head; } }
(7) remove duplicate from sorted list II
82. Remove Duplicates from Sorted List II My Submissions QuestionEditorial Solution Total Accepted: 75944 Total Submissions: 278482 Difficulty: Medium Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list. For example, Given 1->2->3->3->4->4->5, return 1->2->5. Given 1->1->1->2->3, return 2->3.
Analyse: make a dummy pointer, pre = dummy. when pre.next.val == pre.next.next.val, remove the duplicate by pre.next = pre.next.next.
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode deleteDuplicates(ListNode head) { if (head == null || head.next == null) { return head; } ListNode dummy = new ListNode(-1); dummy.next = head; ListNode pre = dummy; while (pre.next != null && pre.next.next != null) { if (pre.next.val == pre.next.next.val) { int val = pre.next.val; while (pre.next != null && pre.next.val == val) { // while (pre.next.val == val) { // null pointer exception pre.next = pre.next.next; } } else { pre = pre.next; } } return dummy.next; } }
(8) merge sorted list
21. Merge Two Sorted Lists My Submissions QuestionEditorial Solution Total Accepted: 135223 Total Submissions: 375466 Difficulty: Easy Merge two sorted linked lists and return it as a new list. The new list should be made by splicing together the nodes of the first two lists.
Analyse :
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode mergeTwoLists(ListNode l1, ListNode l2) { if (null == l1) { return l2; } if (null == l2) { return l1; } ListNode dummy = new ListNode(-1); ListNode node1 = l1; ListNode node2 = l2; ListNode cur = dummy; while (node1 != null && node2 != null) { if (node1.val <= node2.val) { cur.next = new ListNode(node1.val); node1 = node1.next; } else { cur.next = new ListNode(node2.val); node2 = node2.next; } cur = cur.next; } while (node1 != null) { cur.next = new ListNode(node1.val); cur = cur.next; node1 = node1.next; } while (node2 != null) { cur.next = new ListNode(node2.val); node2 = node2.next; cur = cur.next; } return dummy.next; } }
(9) reverse linked list
206. Reverse Linked List My Submissions QuestionEditorial Solution Total Accepted: 119134 Total Submissions: 294600 Difficulty: Easy Reverse a singly linked list.
Analyse : don't use dummy
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode reverseList(ListNode head) { if (head == null || head.next == null) { return head; } ListNode newHead = null; ListNode cur = head; while (cur != null) { ListNode curNext = cur.next; cur.next = newHead; newHead = cur; cur = curNext; } return newHead; } }
(10)delete node in a linked list
237. Delete Node in a Linked List My Submissions QuestionEditorial Solution Total Accepted: 88597 Total Submissions: 200805 Difficulty: Easy Write a function to delete a node (except the tail) in a singly linked list, given only access to that node. Supposed the linked list is 1 -> 2 -> 3 -> 4 and you are given the third node with value 3, the linked list should become 1 -> 2 -> 4 after calling your function. Subscribe to see which companies asked this question
Analyse : the real removed node is its next node
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public void deleteNode(ListNode node) { node.val = node.next.val; node.next = node.next.next; } }
(11)swap nodes in pairs
24. Swap Nodes in Pairs My Submissions QuestionEditorial Solution Total Accepted: 105175 Total Submissions: 294443 Difficulty: Easy Given a linked list, swap every two adjacent nodes and return its head. For example, Given 1->2->3->4, you should return the list as 2->1->4->3. Your algorithm should use only constant space. You may not modify the values in the list, only nodes itself can be changed.
Analyse: first = pre.next; second = pre.next.next; first.next = second.next, second.next = first.next;
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode swapPairs(ListNode head) { if (head == null || head.next == null) { return head; } ListNode dummy = new ListNode(-1); dummy.next = head; ListNode pre = dummy; while (pre.next != null && pre.next.next != null) { ListNode first = pre.next; ListNode second = pre.next.next; first.next = second.next; second.next = first; pre.next = second; pre = first; } return dummy.next; } }
(12) add two number
Add Two Numbers My Submissions QuestionEditorial Solution Total Accepted: 153558 Total Submissions: 644620 Difficulty: Medium You are given two linked lists representing two non-negative numbers. 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. Input: (2 -> 4 -> 3) + (5 -> 6 -> 4) Output: 7 -> 0 -> 8
Analyse: Don't forget the digit != 0 in the last.
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode addTwoNumbers(ListNode l1, ListNode l2) { if (l1 == null) { return l2; } if (l2 == null) { return l1; } ListNode node1 = l1; ListNode node2 = l2; int digit = 0; int sum = 0; ListNode dummy = new ListNode(-1); ListNode cur = dummy; while (node1 != null && node2 != null) { sum = node1.val + node2.val + digit; digit = sum / 10; sum = sum % 10; cur.next = new ListNode(sum); node1 = node1.next; node2 = node2.next; cur = cur.next; } while (node1 != null) { sum = node1.val + digit; digit = sum / 10; sum = sum % 10; cur.next = new ListNode(sum); cur = cur.next; node1 = node1.next; } while (node2 != null) { sum = node2.val + digit; digit = sum / 10; sum = sum % 10; cur.next = new ListNode(sum); cur = cur.next; node2 = node2.next; } // Error if (digit != 0) { cur.next = new ListNode(digit); } return dummy.next; } }
(12)remove linked list elements
203. Remove Linked List Elements My Submissions QuestionEditorial Solution Total Accepted: 68974 Total Submissions: 235494 Difficulty: Easy Remove all elements from a linked list of integers that have value val. Example Given: 1 --> 2 --> 6 --> 3 --> 4 --> 5 --> 6, val = 6 Return: 1 --> 2 --> 3 --> 4 --> 5
Analyse:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode removeElements(ListNode head, int val) { if (head == null) { return head; } ListNode dummy = new ListNode(-1); dummy.next = head; ListNode pre = dummy; while (pre.next != null) { if (pre.next.val == val) { while (pre.next != null && pre.next.val == val) { pre.next = pre.next.next; } } else { pre = pre.next; } } return dummy.next; } }
(13) reverse linkedlist II
92. Reverse Linked List II My Submissions QuestionEditorial Solution Total Accepted: 75506 Total Submissions: 265794 Difficulty: Medium Reverse a linked list from position m to n. Do it in-place and in one-pass. For example: Given 1->2->3->4->5->NULL, m = 2 and n = 4, return 1->4->3->2->5->NULL. Note: Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list.
Analyse: record the startPre, endNext
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode reverseBetween(ListNode head, int m, int n) { if (head == null || m <= 0 || n <= 0) { return head; } // find pre ListNode dummy = new ListNode(-1); dummy.next = head; ListNode pre = dummy; for (int i = 0; i < m - 1; i++) { pre = pre.next; } ListNode start = pre.next; ListNode cur = start.next; for (int i = 0; i < n - m; i++) { start.next = cur.next; cur.next = pre.next; pre.next = cur; cur = start.next; } return dummy.next; } }
(14) Intersection of two linkedlist
160. Intersection of Two Linked Lists My Submissions QuestionEditorial Solution Total Accepted: 79582 Total Submissions: 261697 Difficulty: Easy Write a program to find the node at which the intersection of two singly linked lists begins. For example, the following two linked lists: A: a1 → a2 ↘ c1 → c2 → c3 ↗ B: b1 → b2 → b3 begin to intersect at node c1. Notes: If the two linked lists have no intersection at all, return null. The linked lists must retain their original structure after the function returns. You may assume there are no cycles anywhere in the entire linked structure. Your code should preferably run in O(n) time and use only O(1) memory.
Analyse : fast-slow pointer
(15) intersection of two linkedlist
Given two linked list (without circle), detect if they intersect with each other. Implement: Java: public boolean detectIntersection(ListNode head1, ListNode head2); c++: bool detectIntersection(ListNode* head1, ListNode* head2); Follow up: Return null or the intersection ListNode. Java: public ListNode detectIntersection(ListNode head1, ListNode head2); c++: ListNode* detectIntersection(ListNode* head1, ListNode* head2); Follow up 2: What if the linked lists may have circle? Return null or the intersection node.
Analyse:
class ListNode { int val; ListNode next; ListNode(int x) { val = x; } } public class Solution { public boolean detectIntersection(ListNode head1, ListNode head2) { if (head1 == null || head2 == null) { return false; } int length1 = 0; int length2 = 0; ListNode cur = head1; while (cur != null) { length1++; cur = cur.next; } cur = head2; while (cur != null) { length2++; cur = cur.next; } ListNode fast = null; ListNode slow = null; if (length1 >= length2) { fast = head1; slow = head2; } else { fast = head2; slow = head1; } for (int i = 0; i < Math.abs(length1 - length2); ++i) { fast = fast.next; } while (slow != fast) { slow = slow.next; fast = fast.next; } if (slow != null) { return true; } return false; } public ListNode detectIntersectionFollowUpI(ListNode head1, ListNode head2) { if (head1 == null || head2 == null) { return null; } int length1 = 0; int length2 = 0; ListNode cur = head1; while (cur != null) { length1++; cur = cur.next; } cur = head2; while (cur != null) { length2++; cur = cur.next; } ListNode fast = null; ListNode slow = null; if (length1 >= length2) { fast = head1; slow = head2; } else { fast = head2; slow = head1; } for (int i = 0; i < Math.abs(length1 - length2); ++i) { fast = fast.next; } while (slow != fast) { slow = slow.next; fast = fast.next; } return fast; } public ListNode detectIntersectionFollowUpII(ListNode head1, ListNode head2) { if (head1 == null || head2 == null) { return null; } ListNode cycleNode1 = detectCycle(head1); ListNode cycleNode2 = detectCycle(head2); if (cycleNode1 == null && cycleNode2 == null) { return detectIntersectionFollowUpI(head1, head2); } else if (cycleNode1 == null || cycleNode2 == null) { return null; } else if (cycleNode1 != cycleNode2) { return null; } else { // both them have the cycle ListNode cur = head1; int length1 = 0; int length2 = 0; int flag = 0; while (flag != 2) { if (cur == cycleNode1) { flag++; } length1++; cur = cur.next; } flag = 0; cur = head2; while (flag != 2) { if (cur == cycleNode2) { flag++; } length2++; cur = cur.next; } ListNode fast = null; ListNode slow = null; if (length1 >= length2) { fast = head1; slow = head2; } else { fast = head2; slow = head1; } for (int i = 0; i < Math.abs(length1 - length2); ++i) { fast = fast.next; } while (slow != fast) { slow = slow.next; fast = fast.next; } return fast; } } public static ListNode detectCycle(ListNode head) { if (null == head || head.next == null) { return null; } ListNode slow = head; ListNode fast = head; boolean flag = false; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; if (fast == slow) { flag = true; break; // forget this, so TLE } } if (!flag) { return null; } slow = head; while (fast != slow) { fast = fast.next; slow = slow.next; } return slow; } }
(16) Insertion sort list
147. Insertion Sort List My Submissions QuestionEditorial Solution Total Accepted: 74388 Total Submissions: 248243 Difficulty: Medium Sort a linked list using insertion sort.
Analyse: dummy.next = head is Error.
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode insertionSortList(ListNode head) { if (head == null || head.next == null) { return head; } ListNode dummy = new ListNode(-1); // Error: dummy.next = head; ListNode pre = dummy; ListNode cur = head; while (cur != null) { pre = dummy; while (pre.next!= null && pre.next.val < cur.val) { pre = pre.next; } // insert ListNode temp = pre.next; pre.next = cur; cur = cur.next; pre.next.next = temp; } return dummy.next; } }
(17) reorder list
143. Reorder List My Submissions QuestionEditorial Solution Total Accepted: 67750 Total Submissions: 291628 Difficulty: Medium Given a singly linked list L: L0→L1→…→Ln-1→Ln, reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→… You must do this in-place without altering the nodes' values. For example, Given {1,2,3,4}, reorder it to {1,4,2,3}.
Analyse:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public void reorderList(ListNode head) { if (head == null || head.next == null) { return; // return head; } // find middle ListNode middle = findMiddle(head); // reverse ListNode head2 = middle.next; middle.next = null; ListNode cur = reverseList(head2); // merge ListNode pre = head; while (head != null && cur != null) { ListNode temp = head.next; head.next = cur; cur = cur.next; head.next.next = temp; head = head.next.next; } } // find middle public static ListNode findMiddle(ListNode head) { ListNode fast = head; ListNode slow = head; while (fast != null && fast.next != null) { fast = fast.next.next; slow = slow.next; } return slow; } public static ListNode reverseList(ListNode head) { ListNode dummy = new ListNode(-1); ListNode cur = head; while (cur != null) { ListNode temp = dummy.next; dummy.next = cur; cur =cur.next; dummy.next.next = temp; } return dummy.next; } }
(18) partition list
86. Partition List My Submissions QuestionEditorial Solution Total Accepted: 69718 Total Submissions: 232234 Difficulty: Medium 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. For example, Given 1->4->3->2->5->2 and x = 3, return 1->2->2->4->3->5.
Analyse:
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode partition(ListNode head, int x) { if (head == null || head.next == null) { return head; } ListNode head1 = new ListNode(-1); ListNode head2 = new ListNode(-1); ListNode cur1 = head1; ListNode cur2 = head2; ListNode cur = head; while (cur != null) { if (cur.val < x) { cur1.next = new ListNode(cur.val); cur1 = cur1.next; } else { cur2.next = new ListNode(cur.val); cur2 = cur2.next; } cur = cur.next; } if (head1.next == null) { return head2.next; } cur1.next = head2.next; return head1.next; } }
(19) reverse nodes in k-group
25. Reverse Nodes in k-Group My Submissions QuestionEditorial Solution Total Accepted: 62511 Total Submissions: 223350 Difficulty: Hard Given a linked list, reverse the nodes of a linked list k at a time and return its modified list. If the number of nodes is not a multiple of k then left-out nodes in the end should remain as it is. You may not alter the values in the nodes, only nodes itself may be changed. Only constant memory is allowed. For example, Given this linked list: 1->2->3->4->5 For k = 2, you should return: 2->1->4->3->5 For k = 3, you should return: 3->2->1->4->5
Analyse : find the pre, and the tail, insert the pre.next to tail.next
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode reverseKGroup(ListNode head, int k) { if (head == null || head.next == null || k <= 1) { return head; } ListNode dummy = new ListNode(-1); dummy.next = head; ListNode pre = dummy; ListNode tail = dummy; while (true) { int count = k; while (count > 0 && tail != null) { count--; tail = tail.next; } if (tail == null) { break; } ListNode next = pre.next; // reverse the end of this part-list while (pre.next != tail) { ListNode temp = pre.next; pre.next = pre.next.next; // remove the pre.next temp.next = tail.next; tail.next = temp; } // next step tail = next; pre = next; } return dummy.next; } }
(20) rotate list
61. Rotate List My Submissions QuestionEditorial Solution Total Accepted: 73108 Total Submissions: 315835 Difficulty: Medium Given a list, rotate the list to the right by k places, where k is non-negative. For example: Given 1->2->3->4->5->NULL and k = 2, return 4->5->1->2->3->NULL.
Analyse: find the tail, and the kth node. tail.next = head;
/** * Definition for singly-linked list. * public class ListNode { * int val; * ListNode next; * ListNode(int x) { val = x; } * } */ public class Solution { public ListNode rotateRight(ListNode head, int k) { if (head == null || head.next == null) { return head; } ListNode cur = head; int length = 0; ListNode tail = null; while (cur != null) { tail = cur; cur = cur.next; length++; } k = k % length; if (k == 0) { return head; } // fint the key node cur = head; for (int i = 0; i < length - k - 1; ++i) { cur = cur.next; } ListNode newHead = cur.next; cur.next = null; tail.next = head; return newHead; } }
---------------------------------------------------------------------------------------------------
3, Binary Search
(1)Binary Search
public class Solution { public static void main(String[] args) { int[] nums = {1, 2, 3, 4, 5}; System.out.println(binarySearch(nums, 3)); } public static int binarySearch(int[] nums, int target) { if (null == nums || nums.length == 0) { return -1; } int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { return mid; } else if (nums[mid] < target) { left = mid + 1; } else { right = mid - 1; } } return -1; } }
(2) search insert position
35. Search Insert Position My Submissions QuestionEditorial Solution Total Accepted: 110284 Total Submissions: 292337 Difficulty: Medium Given a sorted array and a target value, return the index if the target is found. If not, return the index where it would be if it were inserted in order. You may assume no duplicates in the array. Here are few examples. [1,3,5,6], 5 → 2 [1,3,5,6], 2 → 1 [1,3,5,6], 7 → 4 [1,3,5,6], 0 → 0
Analyse: use binary search
public class Solution { public int searchInsert(int[] nums, int target) { if (null == nums || nums.length == 0) { return -1; } // binary search int left = 0; int right = nums.length - 1; int result = 0; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { return mid; } else if(nums[mid] < target) { result = mid + 1; left = mid + 1; } else { right = mid - 1; } } return result; } }
(3) search in rotated sorted array
33. Search in Rotated Sorted Array My Submissions QuestionEditorial Solution Total Accepted: 106703 Total Submissions: 348560 Difficulty: Hard Suppose a sorted array 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). You are given a target value to search. If found in the array return its index, otherwise return -1. You may assume no duplicate exists in the array.
Analyse: find the part that is increasing strictly
public class Solution { public int search(int[] nums, int target) { if (null == nums || nums.length == 0) { return -1; } int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { return mid; } if (nums[mid] >= nums[left]) { // Error: if (nums[mid] > nums[left]) { if (nums[mid] > target && target >= nums[left]) { right = mid - 1; } else { left = mid + 1; } } else { if (nums[mid] < target && target <= nums[right]) { left = mid + 1; } else { right = mid - 1; } } } return -1; } }
(4) search in rotated sorted array
81. Search in Rotated Sorted Array II My Submissions QuestionEditorial Solution Total Accepted: 65486 Total Submissions: 203708 Difficulty: Medium Follow up for "Search in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Write a function to determine if a given target is in the array.
Analyse : remember this: because there is duplicates, find the part must be increasing strictly
public class Solution { public static boolean search(int[] nums, int target) { if (null == nums || nums.length == 0) { return false; } int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (nums[mid] == target) { return true; } if (nums[mid] > nums[left]) { if (nums[mid] > target && target >= nums[left]) { right = mid - 1; } else { left = mid + 1; } } else if (nums[mid] < nums[right]) { if (nums[mid] < target && target <= nums[right]) { left = mid + 1; } else { right = mid - 1; } } else { // Error: forget this. now the time coplexity may be O(n) if (nums[left] == target) { return true; } left++; } } return false; } }
(5) Sqrt(x)
69. Sqrt(x) My Submissions QuestionEditorial Solution Total Accepted: 98516 Total Submissions: 384120 Difficulty: Medium Implement int sqrt(int x). Compute and return the square root of x.
Analyse: use x / mid == mid
public class Solution { public int mySqrt(int x) { if (x <= 1) { return x; } int left = 1; int right = x / 2; int result = 0; while (left <= right) { int mid = left + (right - left) / 2; if (x / mid == mid) { return mid; } if (x / mid > mid) { result = mid; left = mid + 1; } else { right = mid - 1; } } return result; } }
(6)Find Minimum in rotated sorted array
153. Find Minimum in Rotated Sorted Array My Submissions QuestionEditorial Solution Total Accepted: 96998 Total Submissions: 263744 Difficulty: Medium Suppose a sorted array 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.
Analyse:return nums[mid] when nums[mid] < nums[mid - 1]
public class Solution { public int findMin(int[] nums) { // analyse : return when nums[i] < nums[i - 1] if (null == nums || nums.length == 0) { return -1; } if (nums[0] <= nums[nums.length - 1]) { return nums[0]; } int left = 0; int right = nums.length - 1; while (left <= right) { int mid = left + (right - left) / 2; if (mid > 0 && nums[mid] < nums[mid - 1]) { return nums[mid]; } if(nums[mid] >= nums[left] && nums[mid] >= nums[right]) { left = mid + 1; } else { right = mid - 1; } } return -1; } }
(7) search a 2D matrix
74. Search a 2D Matrix My Submissions QuestionEditorial Solution Total Accepted: 83378 Total Submissions: 243517 Difficulty: Medium 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. For example, Consider the following matrix: [ [1, 3, 5, 7], [10, 11, 16, 20], [23, 30, 34, 50] ] Given target = 3, return true.
Analyse : binary search the row of target,then find it in this row.
public class Solution { public boolean searchMatrix(int[][] matrix, int target) { if (null == matrix || matrix.length == 0) { return false; } int n = matrix.length; // number of rows int m = matrix[0].length; // number of columns // find the row of target int up = 0; int down = n - 1; int row = -1; while (up <= down) { int mid = up + (down - up) / 2; if (matrix[mid][0] == target) { return true; } else if (matrix[mid][0] < target) { row = mid; up = mid + 1; } else { down = mid - 1; } } if (row == -1) { return false; } // find the target int left = 0; int right = m - 1; while (left <= right) { // Error: while (left < right) { int mid = left + (right - left) / 2; if (matrix[row][mid] == target) { return true; } else if (matrix[row][mid] < target) { left = mid + 1; } else { right = mid - 1; } } return false; } }
(8) Divide Two Integer
29. Divide Two Integers My Submissions QuestionEditorial Solution Total Accepted: 70100 Total Submissions: 444555 Difficulty: Medium Divide two integers without using multiplication, division and mod operator. If it is overflow, return MAX_INT. Subscribe to see which companies asked this question
Analyse:
public class Solution { public int divide(int dividend, int divisor) { if (divisor == 0) { return dividend >= 0 ? Integer.MAX_VALUE : Integer.MIN_VALUE; } if (dividend == 0) { return 0; } if (dividend == Integer.MIN_VALUE && divisor == -1) { return Integer.MAX_VALUE; } boolean isNegative = dividend < 0 && divisor > 0 || dividend > 0 && divisor < 0; long a = Math.abs((long)dividend); long b = Math.abs((long)divisor); int result = 0; while (a >= b) { int shift = 0; while (a >= (b << shift)) { shift++; } a = a - (b << (shift - 1)); result += 1 << (shift - 1); } return isNegative ? -result : result; } }
(9)two sum follow up
Two Sum - follow up Given an array of integers (no duplicate), find two numbers such that they add up to a specific target number. The function twoSum should return the two numbers such that they add up to the target, where number1 must be less than number2. You may assume that each input would have exactly one solution. Java: public ArrayList> twoSum(int[] nums, int target);
Analyse and answer: if nums[left] + nums[right] == target, you need to check nums[right--], because the duplicate. then left++;
import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; public class TwoSumFollowUp { public static void main(String[] args) { // int[] a = {1, 3, 3, 4, 2, 1, }; // System.out.println(twoSum(a, 4)); // int[] a = {1, 3, 5, 2, 4, 6, 1}; // System.out.println(twoSum(a, 6)); int[] a = {1, 1, 1, 1}; System.out.println(twoSum(a, 2)); } public static ArrayList> twoSum(int[] nums, int target) { ArrayList > res = new ArrayList(); if (nums == null || nums.length == 0) { return res; } Arrays.sort(nums); int left = 0; int right = nums.length - 1; while (left < right) { if (nums[left] + nums[right] == target) { ArrayList list = new ArrayList(); list.add(nums[left]); list.add(nums[right]); res.add(list); int tempRight = right - 1; while (left < tempRight && nums[tempRight] + nums[left] == target) { res.add(list); tempRight--; } left++; } else if (nums[left] + nums[right] > target) { right--; } else { left++; } } return res; } }
(10)
---------------------------------------------------------------------------------------------------
2,Array
(1)How to implement Java ArrayList
public class ArrayList { private int capacity; private int size; private int[] data; public ArrayList(int capacity_) { capacity = capacity_; size = 0; data = new int[capacity]; } public int get(int index) { if (index < 0 || index >= size) { // throw Exception System.out.println("ArrayIndexOutOfBoundsException: " + index); } return data[index]; } public void set(int index, int value) { if (index < 0 || index >= size) { System.out.println("ArrayIndexOutOfBoundsException: " + index); } data[index] = value; } public void add(int index, int value) { if (index < 0 || index > size) { System.out.println("ArrayIndexOutOfBoundsException: " + index); } if (size == capacity) { resize(); } size++; for (int i = size - 1; i >= index + 1; --i) { data[i] = data[i - 1]; } data[index] = value; } private void resize() { capacity *= 2; int[] tempData = new int[size]; for (int i = 0; i < size; ++i) { tempData[i] = data[i]; } data = new int[capacity]; for (int i = 0; i < size; ++i) { data[i] = tempData[i]; } } public void remove(int index) { if (index < 0 || index >= size) { System.out.println("ArrayIndexOutOfBoundsException: " + index); } size--; for (int i = index; i < size; ++i) { data[i] = data[i + 1]; } } public static void main(String[] args) { int[] a = {1}; System.out.println(a[-1]); } }
(2) Two sum
1. Two Sum My Submissions QuestionEditorial Solution Total Accepted: 247444 Total Submissions: 1017480 Difficulty: Easy Given an array of integers, return indices of the two numbers such that they add up to a specific target. You may assume that each input would have exactly one solution. Example: Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1]. UPDATE (2016/2/13): The return format had been changed to zero-based indices. Please read the above updated description carefully. Subscribe to see which companies asked this question
Analyse: Use the HashMap to save (target - nums[i], i)
public class Solution { public int[] twoSum(int[] nums, int target) { int[] res = new int[2]; if (null == nums || nums.length == 0) { return res; } HashMapmap = new HashMap(); for (int i = 0; i < nums.length; ++i) { if (!map.containsKey(nums[i])) { map.put(target - nums[i], i); } else { res[0] = map.get(nums[i]); res[1] = i; break; } } return res; } } /** * All Error: * 1, Compile Error : Line 20: error: unclosed comment. because the space of '*'' and '/'' * 2, map.add. carelessness */
(3)Three sum (3 sum)
15. 3Sum My Submissions QuestionEditorial Solution Total Accepted: 124429 Total Submissions: 648520 Difficulty: Medium Given an array S of n integers, are there elements a, b, c in S 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. For example, given array S = [-1, 0, 1, 2, -1, -4], A solution set is: [ [-1, 0, 1], [-1, -1, 2] ]
Analyse : we must start the loop for i == 0, and the range is from big to small, because we must skip the duplicates
public class Solution { public List> threeSum(int[] nums) { List
> result = new ArrayList(); if (nums == null || nums.length < 3) { return result; } Arrays.sort(nums); for (int i = 0; i < nums.length - 2; ++i) { if (i != 0 && nums[i] == nums[i - 1]) { continue; } int left = i + 1; int right = nums.length - 1; while (left < right) { int sum = nums[left] + nums[right] + nums[i]; if (sum == 0) { result.add(Arrays.asList(nums[i], nums[left], nums[right])); left++; right--; while (left < right && nums[left] == nums[left - 1]) { left++; } while (left < right && nums[right] == nums[right + 1]) { right--; } } else if (sum < 0) { left++; } else { right--; } } } return result; } } /** * All Error: * Time Limit Exceeded : i start from 0. we can skip duplicates * */
(4)K-sum's time complexity
2-sum : O(nlogn), because the sort's time complexity.
k-sum: O(n ^ (k - 1)), Use the two pointer.
(5)reverse the Array
import java.util.Arrays; public class Solution { public static void main(String[] args) { int[] a = {1, 2, 3, 6, 7}; reverseArray(a); System.out.println(Arrays.toString(a)); } public static void reverseArray(int[] nums) { if (nums == null || nums.length == 0) { return; } int left = 0; int right = nums.length - 1; while (left < right) { // swarp int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; left++; right--; } } }
(6)odd Even sort
Given an array of integers, sort them so that all odd integers come before even integers. The order of elements can be changed. The order of sorted odd numbers and even numbers doesn't matter. Examples: Input: {4, 3, 5, 2, 1, 11, 0, 8, 6, 9} Output: {9, 3, 5, 11, 1, 2, 0, 8 , 6
Analyse:use the quick-sort's thinking.
import java.util.Arrays; public class Solution { public static void main(String[] args) { int[] nums = {4, 3, 5, 2, 1, 11, 0, 8, 6, 9}; oddEvenSort(nums); System.out.println(Arrays.toString(nums)); } public static void oddEvenSort(int[] nums) { if (null == nums || nums.length == 0) { return; } int left = 0; int right = nums.length - 1; while (left < right) { while (left < right && nums[left] % 2 == 1) { left++; } while (left < right && nums[right] % 2 == 0) { right--; } nums[left] = nums[left] ^ nums[right]; nums[right] = nums[left] ^ nums[right]; nums[left] = nums[left] ^ nums[right]; } } }
(7)Pivot Sort
Given an array of integers and a target number, sort them so that all numbers that are smaller than the target always come before the numbers that are larger than the target. The order of elements can be changed. Examples: Input: {4, 9, 5, 2, 1, 11, 0, 8, 6, 3}, 7 Output: {4, 3, 5, 2, 1, 6, 0, 8,
Analyse: quick-sort.
import java.util.Arrays; public class Solution { public static void main(String[] args) { int[] nums = {4, 9, 5, 2, 1, 11, 0, 8, 6, 3}; int target = 7; pivotSort(nums, target); System.out.println(Arrays.toString(nums)); } public static void pivotSort(int[] nums, int target) { if (null == nums || nums.length == 0) { return; } int left = 0; int right = nums.length - 1; while (left < right) { while (left < right && nums[left] <= target) { left++; } while (left < right && nums[right] > target) { right--; } if (nums[left] != nums[right]) { nums[left] = nums[left] ^ nums[right]; nums[right] = nums[left] ^ nums[right]; nums[left] = nums[left] ^ nums[right]; } } } }
(8)Remove Element
Remove Element Given an array and a value, remove all instances of that value in place and return the new length. The order of elements can be changed. It doesn't matter what you leave beyond the new length. Examples: Input: {10, 9, 5, 3, 9, 9, 8, 6, 7}, 9 Output: {10, 5, 3, 8, 6, 7, X, X, X}, 6 public int removeElement(int[] nums,
Analyse : put the last elment replace the target
public class Solution { public int removeElement(int[] nums, int val) { if (nums == null || nums.length == 0) { return 0; } int index = 0; int newLen = nums.length; while (index < newLen) { nums[index] = nums[index] == val ? nums[--newLen] : nums[index++]; } return newLen; } }
(9) Merge Two Sorted Array
88. Merge Sorted Array My Submissions QuestionEditorial Solution Total Accepted: 105839 Total Submissions: 348933 Difficulty: Easy Given two sorted integer arrays nums1 and nums2, merge nums2 into nums1 as one sorted array. Note: You may assume that nums1 has enough space (size that is greater or equal to m + n) to hold additional elements from nums2. The number of elements initialized in nums1 and nums2 are m and n respectively. Subscribe to see which companies asked this question
Analyse:
public class Solution { public void merge(int[] nums1, int m, int[] nums2, int n) { // if (nums1 == null || nums2 == null || m == 0 || n == 0) { // return; // } This is a Error, Because m is not the real length if (nums1 == null || nums1.length == 0 || nums2 == null || nums2.length == 0) { return; } int len = nums1.length - 1; int index1 = m - 1; int index2 = n - 1; while (index1 >= 0 && index2 >= 0) { if (nums1[index1] > nums2[index2]) { nums1[len--] = nums1[index1--]; } else { nums1[len--] = nums2[index2--]; } } while (index1 >= 0) { nums1[len--] = nums1[index1--]; } while (index2 >= 0) { nums1[len--] = nums2[index2--]; } } }
(10)Spiral Matrix
54. Spiral Matrix My Submissions QuestionEditorial Solution Total Accepted: 62861 Total Submissions: 273744 Difficulty: Medium Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order. For example, Given the following matrix: [ [ 1, 2, 3 ], [ 4, 5, 6 ], [ 7, 8, 9 ] ] You should return [1,2,3,6,9,8,7,4,5].
Analyse: four index : left, righ, up, down. four direction .
public class Solution { public static ListspiralOrder(int[][] matrix) { List result= new ArrayList(); if (null == matrix || matrix.length == 0) { return result; } int left = 0; int right = matrix[0].length - 1; int up = 0; int down = matrix.length - 1; while (left <= right && up <= down) { // left -> right for (int j = left; j <= right && up <= down; ++j) { result.add(matrix[up][j]); } up++; // up -> down for (int i = up; i <= down && left <= right; ++i) { result.add(matrix[i][right]); } right--; // right -> left for (int j = right; j >= left && up <= down; --j) { result.add(matrix[down][j]); } down--; // down -> up for (int i = down; i >= up && left <= right; --i) { result.add(matrix[i][left]); } left++; } return result; } }
(11) Missing Number
Analyse: result = sum(i : 0 -> n) - sum(nums[i])
public class Solution { public int missingNumber(int[] nums) { if (null == nums || nums.length == 0) { return 0; } int sum = 0; for (int i = 0; i < nums.length; ++i) { sum += i - nums[i]; } return sum + nums.length; } }
(12) Majority Element
169. Majority Element My Submissions QuestionEditorial Solution Total Accepted: 121829 Total Submissions: 289252 Difficulty: Easy Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times. You may assume that the array is non-empty and the majority element always exist in the array.
Analyse : the majority element's nums > all others.
public class Solution { public int majorityElement(int[] nums) { if (null == nums || nums.length == 0) { return -1; } int result = 0; int count = 0; for (int i = 0; i < nums.length; ++i) { if (count == 0) { result = nums[i]; count++; } else if (nums[i] == result) { count++; } else { count--; } } return result; } }
(13)Partition array
public class PartitionArray { public static int partitionArray(int[] nums, int k) { if (nums == null || nums.length == 0) { return 0; } int left = 0; int right = nums.length - 1; while (left < right) { while (left < right && nums[left] < k) { left++; } if (left == right) { return right + 1; } while (left < right && nums[right] >= k) { right--; } // swap if (left < right) { int temp = nums[left]; nums[left] = nums[right]; nums[right] = temp; left++; right--; } } return left; } }
------------------------------------------------------------------------------------------------
1,time complexity:
if the recurrence equation is T(n) = aT(b/n) + n ^ c。
if logb a > c , T(n) = n ^ (logb a)
if logb a == c, T(n) = n ^ c * logn
if logb a < c , T(n) = n ^ c