1. 程式人生 > >打卡2

打卡2

-a nco builder rem 轉換成 can exp ive ems

1. 155. Min Stack

https://leetcode.com/problems/min-stack/#/description

借助一個棧存儲最小值, 當入棧值小於等於當前最小值時, 才加入中間站..當最小值被被pop出時, 中間棧才pop最小值

中間站初始的時候要加入一個第一個值

public class MinStack {

private Stack<Integer> stack = new Stack<Integer>();

private Stack<Integer> minStack = new Stack<Integer>();

public MinStack() {

// do initialize if necessary

stack = new Stack<Integer>();

minStack = new Stack<Integer>();*/

}

public void push(int number) {

// write your code here

stack.push(number);

if (minStack.empty()) {

minStack.push(number);

} else if (number <= minStack.peek()) {

minStack.push(number);

}

}

public int pop() {

// write your code here

if (stack.peek().equals(minStack.peek())) {

minStack.pop();

}

return stack.pop();

}

public int min() {

// write your code here

return minStack.peek();

}

}

一個站, 一個動態的min

public class MinStack {

Stack<Integer> stack;

int min=Integer.MAX_VALUE;;

/** initialize your data structure here. */

public MinStack() {

stack = new Stack<>();

}

public void push(int x) {

if(x<=min)

{

stack.push(min);

min = x;

}

stack.push(x);

}

public void pop() {

if(stack.pop() == min)

min = stack.pop();

}

public int top() {

return stack.peek();

}

public int getMin() {

return min;

}

}

2. 514. Freedom Trail

3. 515. Find Largest Value in Each Tree Row

https://leetcode.com/submissions/detail/104030319/

public List<Integer> largestValues(TreeNode root) {

List<Integer> ans = new ArrayList<>();

if (root == null) return ans;

Queue<TreeNode> q = new LinkedList<>();

q.offer(root);

while (!q.isEmpty()) {

int size = q.size();

int max = Integer.MIN_VALUE;

while (size > 0) {

TreeNode cur = q.poll();

size--;

max = Math.max(cur.val, max);

if (cur.left != null) {

q.offer(cur.left);

}

if (cur.right != null) {

q.offer(cur.right);

}

}

ans.add(max);

}

return ans;

}

4. 513. Find Bottom Left Tree Value

https://leetcode.com/problems/find-bottom-left-tree-value/#/description

http://www.cnblogs.com/grandyang/p/6405128.html

bfs

public int findBottomLeftValue(TreeNode root) {

if (root == null) return -1;

Queue<TreeNode> q = new LinkedList<>();

q.offer(root);

int ans = 1;

while (!q.isEmpty()) {

int size = q.size();

for (int i = 0; i < size; i++) {

TreeNode cur = q.poll();

if (cur.left != null) {

q.offer(cur.left);

}

if (cur.right != null) {

q.offer(cur.right);

}

if (i == 0) {

ans = cur.val;

}

}

}

return ans;

}

Dfs

public class Solution {

int maxDeep = 0;

int ans = 0;

public int findBottomLeftValue(TreeNode root) {

if (root == null) return -1;

helper(root, 0);

return ans;

}

private void helper(TreeNode root, int deep) {

if (root == null) {

return;

}

if (deep >= maxDeep) {

maxDeep++;

ans = root.val;

}

helper(root.left, deep + 1);

helper(root.right, deep + 1);

}

}

5. 215. Kth Largest Element in an Array

https://leetcode.com/problems/kth-largest-element-in-an-array/#/solutions

https://leetcode.com/problems/kth-largest-element-in-an-array/#/solutions

數組能排序的先排序

public int findKthLargest(int[] nums, int k) {

int n = nums.length;

Arrays.sort(nums);

return nums[n-k];

}

快速排序

public int findKthLargest(int[] nums, int k) {

if (nums == null || nums.length == 0) {

return Integer.MAX_VALUE;

}

int ans = helper(nums, nums.length - k + 1, 0, nums.length - 1);

return ans;

}

private int helper(int[] nums, int k, int beg, int end) {

int pivot = nums[end];

int i = beg, j = end;

while (i < j) {

if (nums[i] > pivot) {

j--;

swap( i, j,nums);

} else {

i++;

}

}

swap(j, end, nums);

if (i + 1 - beg == k) {

return pivot;

} else if (i + 1 - beg < k) {

return helper(nums, k - i - 1 + beg, i + 1, end);

} else {

return helper(nums, k, beg, i - 1);

}

}

private void swap (int a, int b, int[] nums) {

int temp = nums[b];

nums[b] = nums[a];

nums[a] = temp;

}

6. 116. Populating Next Right Pointers in Each Node ---- 空間一定

http://www.cnblogs.com/grandyang/p/4288151.html

http://www.cnblogs.com/EdwardLiu/p/3978458.html

https://leetcode.com/problems/populating-next-right-pointers-in-each-node/#/description

層次遍歷

public class Solution {

public void connect(TreeLinkNode root) {

TreeLinkNode pre = null;

if (root == null) return;

Queue<TreeLinkNode> queue = new LinkedList<>();

queue.offer(root);

while (!queue.isEmpty()) {

int size = queue.size();

for (int i=0; i<size; i++) {

TreeLinkNode cur = queue.poll();

if (pre == null) pre = cur;

else {

pre.next = cur;

pre = cur;

}

if (cur.left != null) queue.offer(cur.left);

if (cur.right != null) queue.offer(cur.right);

}

pre = null;

}

}

}

層次遞進法—記住下一層, 下一層有才對其進行遍歷, 內部循環操作本層的子節點

public class Solution {

public void connect(TreeLinkNode root) {

if(root==null) return;

root.next = null;

TreeLinkNode cur = root;

TreeLinkNode nextLeftmost = null;

//遞進while(cur.left!=null){

//遞進nextLeftmost = cur.left; // save the start of next level, 當作下次內循環的開始點並判斷是否有下次循環

//層次 while(cur!=null){

cur.left.next=cur.right;

cur.right.next = cur.next==null? null : cur.next.left;

cur=cur.next;

}

cur=nextLeftmost; // point to next level

}

}

}

7. 117. Populating Next Right Pointers in Each Node II -----空間一定

https://leetcode.com/problems/populating-next-right-pointers-in-each-node-ii/#/description

http://www.cnblogs.com/EdwardLiu/p/3978460.html

bfs—同上---不可以

public class Solution {

public void connect(TreeLinkNode root) {

TreeLinkNode pre = null;

if (root == null) return;

Queue<TreeLinkNode> queue = new LinkedList<>();

queue.offer(root);

while (!queue.isEmpty()) {

int size = queue.size();

for (int i=0; i<size; i++) {

TreeLinkNode cur = queue.poll();

if (pre == null) pre = cur;

else {

pre.next = cur;

pre = cur;

}

if (cur.left != null) queue.offer(cur.left);

if (cur.right != null) queue.offer(cur.right);

}

pre = null;

}

}

}

層次遞進法 ---需要記號: 記住本層 的頭結點, 本層遍歷的節點, 上一層遍歷的節點

public void connect(TreeLinkNode root) {

public void connect(TreeLinkNode root) {

if (root == null) return;

TreeLinkNode temp = null;// 本層實現遍歷的中介點

TreeLinkNode head = null;// 記住本層的頭節點, 下次作為是否開啟內循環的判斷和內循環的開始點

TreeLinkNode cur = root;// 上一層的遍歷點

while (cur != null) {

// 內循環遍歷上一層的節點

while (cur != null) {

// 分情況看節點是否存在

if (cur.left != null) {

// 本層節點的遍歷節點是否存在

if (temp != null) {

temp.next = cur.left;

} else {

//不存在的話先保存頭結點

head = cur.left;

}

//遍歷的傳遞

temp = cur.left;

}

if (cur.right != null) {

if (temp != null) {

temp.next = cur.right;

} else {

head = cur.right;

}

temp = cur.right;

}

// 上層遍歷的傳遞

cur = cur.next;

}

//開啟下層循環, 重置下層的頭結點和遍歷節點

cur = head;

temp = null;

head = null;

}

}

8. 129. Sum Root to Leaf Numbers---

遞歸的題分為考察輸入值(頭到尾改變)、輸出值(直到尾部才開始改變—多為先遞歸再操作然後作為返回值的 )二叉樹常用分治

http://www.cnblogs.com/grandyang/p/4036961.html

https://leetcode.com/problems/sum-root-to-leaf-numbers/#/description

http://blog.csdn.net/linhuanmars/article/details/22913699

這是一道樹的題目,一般使用遞歸來做,主要就是考慮遞歸條件和結束條件。這道題思路還是比較明確的,目標是把從根到葉子節點的所有路徑得到的整數都累加起來,遞歸條件即是題目要求—是改動遞歸的輸入值、返回值?: 把當前的sum乘以10並且加上當前節點傳入下一函數,進行遞歸,最終把左右子樹的總和相加。結束條件的話就是如果一個節點是葉子,那麽我們應該累加到結果總和中,如果節點到了空節點,則不是葉子節點,不需要加入到結果中,直接返回0即可。算法的本質是一次先序遍歷,所以時間是O(n),空間是棧大小,O(logn)。

public int sumNumbers(TreeNode root) {

int ans = helper(root, 0);

return ans;

}

private int helper(TreeNode root, int sum) {

// 處理空節點

if (root == null) return 0;

//處理葉結點

if (root.left == null && root.right == null) {

return sum * 10 + root.val;

}

// 在遍歷的時候的操作, 只是改變輸入值, 每一層都有返回, 畫圖! 回溯!

int left = helper(root.left, sum * 10 + root.val);

int right = helper(root.right, sum * 10 + root.val);

return left + right;

}

9. 581. Shortest Unsorted Continuous Subarray

數組的題常用方法 :排序、最大值指針邊走邊找、最小值指針邊走邊找,數組的其他指針位置—順序遍歷, 逆序遍歷,其他指針與最大值指針比較的後果或最小值指針

https://leetcode.com/problems/shortest-unsorted-continuous-subarray/#/description

public int findUnsortedSubarray(int[] nums) {

int n = nums.length;

if (n == 0 || nums == null) {

return 0;

}

int max = nums[0], min = nums[n - 1], beg = - 2, end = - 1;

for (int i = 1; i < n; i++) {

max = Math.max(max, nums[i]);

min = Math.min(min, nums[n - 1 - i]);

if (nums[i] < max) end = i;

if (nums[n - 1 - i] > min) beg = n - 1- i;

}

return end - beg + 1;

}

10. 241. Different Ways to Add Parentheses

字符串的分治法,和遞歸一樣,找遞歸條件-函數輸入值和返回值,結束條件—葉節點和空節點的處理

http://www.cnblogs.com/EdwardLiu/p/5068637.html

https://leetcode.com/problems/different-ways-to-add-parentheses/#/description

public class Solution {

public List<Integer> diffWaysToCompute(String input) {

List<Integer> res = new ArrayList<Integer>();

if (input==null || input.length()==0) return res;

for (int i=0; i<input.length(); i++) { //結束條件 i = input.length()

char c = input.charAt(i);

if (!isOperator(c)) continue; //遞歸條件

List<Integer> left = diffWaysToCompute(input.substring(0, i));

List<Integer> right = diffWaysToCompute(input.substring(i+1));

//遞歸條件---返回值

for (int j=0; j<left.size(); j++) {

for (int k=0; k<right.size(); k++) {

int a = left.get(j);

int b = right.get(k);

res.add(calc(a,b,c));

}

}

}

// 葉節點的處理

if (res.size() == 0) { //input is not null or size==0, but res.size()==0, meaning input is just a number

res.add(Integer.valueOf(input));

}

return res;

}

public boolean isOperator(char c) {

if (c==‘+‘ || c==‘-‘ || c==‘*‘) return true;

return false;

}

public int calc(int a, int b, char c) {

int res = Integer.MAX_VALUE;

switch(c) {

case ‘+‘: res = a+b; break;

case ‘-‘: res = a-b; break;

case ‘*‘: res = a*b; break;

}

return res;

}

}

11. 169. Majority Element

https://leetcode.com/submissions/detail/104321887/

分治法 數組的分治法: 返回值類型,變量類型, 出口, 分治, 題目要求--返回值,, 難點在與題目要求的理解和轉換成結果類型,

public class Solution {

public int majorityElement(int[] nums) {

return helper(nums, 0, nums.length-1);

}

//確定返回值類型(根據在下一次遞歸中的作用, 或者題目的返回值類型)

private int helper(int[] nums, int lo, int hi) {

//遞歸出口

if (lo == hi) return nums[lo];

int mid = lo + (hi - lo) / 2;

//分治

int left = helper(nums, lo, mid);

int right = helper(nums, mid+1, hi);

//開始對分治後的小分支進行操作: 根據題目要求用TC寫一下, 準備進行返回了

// 優化的好啊, 如果相等不用判斷了

if (left == right) return left;

else {

int l = 0, r = 0;

for (int i = lo; i <= hi; i++) {

if (nums[i] == left) l++;

if (nums[i] == right) r++;

}

return l > r ? left : right;

}

}

}

根據majority 的特性---考點—提取成算法

public int majorityElement(int[] nums) {

int majority = nums[0], count = 1;

for (int i = 1; i < nums.length; i++) {

if (count == 0) {

majority = nums[i];

count++;

} else if (nums[i] == majority) {

count++;

} else {

count--;

}

}

return majority;

}

hashMap 法鍵值對

public class Solution {

public int majorityElement(int[] num) {

int n = num.length;

HashMap<Integer, Integer> map = new HashMap<Integer, Integer>();

for (int elem : num) {

if (map.containsKey(elem)) {

map.put(elem, map.get(elem)+1);

}

else {

map.put(elem, 1);

}

}

for (int item : map.keySet()) {

if (map.get(item) > n/2) {

return item;

}

}

return -1;

}

}

12. 229. Majority Element II

https://leetcode.com/problems/majority-element-ii/#/description

http://www.cnblogs.com/EdwardLiu/p/5060185.html

public List<Integer> majorityElement(int[] nums) {

List<Integer> list = new ArrayList<>();

if (nums == null || nums.length == 0) {

return list;

}

if (nums.length == 1) {

list.add(nums[0]);

return list;

}

int ans1 = 0, ans2 = 0;

int count1 = 0, count2 = 0;

for (int i = 0; i < nums.length; i++) {

if (nums[i] != ans1 && nums[i] != ans2) {

if (count1 == 0) {

ans1 = nums[i];

count1++;

} else if (count2 == 0) {

ans2 = nums[i];

count2++;

} else {

count1--;

count2--;

}

} else if (nums[i] == ans1) {

count1++;

} else {

count2++;

}

}

count1 = 0;

count2 = 0;

for (int i : nums) {

if (i == ans1) {

count1++;

} else if (i == ans2) {

count2++;

}

}

if (count1 > nums.length / 3) {

list.add(ans1);

}

if (count2 > nums.length / 3) {

list.add(ans2);

}

return list;

}

13. 315. Count of Smaller Numbers After Self

https://leetcode.com/problems/count-of-smaller-numbers-after-self/#/description

BST

public class Solution {

private class TreeNode {

public int val;

public int count = 1;

public TreeNode left, right;

public TreeNode(int val) {

this.val = val;

}

}

public List<Integer> countSmaller(int[] nums) {

List<Integer> res = new ArrayList<>();

if(nums == null || nums.length == 0) {

return res;

}

TreeNode root = new TreeNode(nums[nums.length - 1]);

res.add(0);

for(int i = nums.length - 2; i >= 0; i--) {

int count = addNode(root, nums[i]);

res.add(count);

}

Collections.reverse(res);

return res;

}

private int addNode(TreeNode root, int val) {

int curCount = 0;

while(true) {

if(val <= root.val) {

root.count++; // add the inversion count

if(root.left == null) {

root.left = new TreeNode(val);

break;

} else {

root = root.left;

}

} else {

curCount += root.count;

if(root.right == null) {

root.right = new TreeNode(val);

break;

} else {

root = root.right;

}

}

}

return curCount;

}

}

Merge sort

https://leetcode.com/problems/count-of-smaller-numbers-after-self/#/solutions

int[] count;

public List<Integer> countSmaller(int[] nums) {

List<Integer> res = new ArrayList<Integer>();

count = new int[nums.length];

int[] indexes = new int[nums.length];

for(int i = 0; i < nums.length; i++){

indexes[i] = i;

}

mergesort(nums, indexes, 0, nums.length - 1);

for(int i = 0; i < count.length; i++){

res.add(count[i]);

}

return res;

}

private void mergesort(int[] nums, int[] indexes, int start, int end){

if(end <= start){

return;

}

int mid = (start + end) / 2;

mergesort(nums, indexes, start, mid);

mergesort(nums, indexes, mid + 1, end);

merge(nums, indexes, start, end);

}

private void merge(int[] nums, int[] indexes, int start, int end){

int mid = (start + end) / 2;

int left_index = start;

int right_index = mid+1;

int rightcount = 0;

int[] new_indexes = new int[end - start + 1];

int sort_index = 0;

while(left_index <= mid && right_index <= end){

if(nums[indexes[right_index]] < nums[indexes[left_index]]){

new_indexes[sort_index] = indexes[right_index];

rightcount++;

right_index++;

}else{

new_indexes[sort_index] = indexes[left_index];

count[indexes[left_index]] += rightcount;

left_index++;

}

sort_index++;

}

while(left_index <= mid){

new_indexes[sort_index] = indexes[left_index];

count[indexes[left_index]] += rightcount;

left_index++;

sort_index++;

}

while(right_index <= end){

new_indexes[sort_index++] = indexes[right_index++];

}

for(int i = start; i <= end; i++){

indexes[i] = new_indexes[i - start];

}

}

14. 327. Count of Range Sum

https://leetcode.com/problems/count-of-range-sum/#/solutions

public int countRangeSum(int[] nums, int lower, int upper) {

int n = nums.length;

long[] sums = new long[n + 1];

for (int i = 0; i < n; ++i)

sums[i + 1] = sums[i] + nums[i];

return countWhileMergeSort(sums, 0, n + 1, lower, upper);

}

private int countWhileMergeSort(long[] sums, int start, int end, int lower, int upper) {

if (end - start <= 1) return 0;

int mid = (start + end) / 2;

int count = countWhileMergeSort(sums, start, mid, lower, upper)

+ countWhileMergeSort(sums, mid, end, lower, upper);

int j = mid, k = mid, t = mid;

long[] cache = new long[end - start];

for (int i = start, r = 0; i < mid; ++i, ++r) {

while (k < end && sums[k] - sums[i] < lower) k++;

while (j < end && sums[j] - sums[i] <= upper) j++;

while (t < end && sums[t] < sums[i]) cache[r++] = sums[t++];

cache[r] = sums[i];

count += j - k;

}

System.arraycopy(cache, 0, sums, start, t - start);

return count;

}

15. 148. Sort List

https://leetcode.com/problems/sort-list/#/description

public ListNode sortList(ListNode head) {

// write your code here

if (head == null || head.next == null) {

return head;

}

ListNode mid = findMid(head);

// 要從mid的下一個查找不然最後一次findmid會棧溢出

ListNode right = sortList(mid.next);

// 要讓mid的下一個為空, 不然會死循環

mid.next = null;

ListNode left = sortList(head);

return merge(left, right);

}

private ListNode merge(ListNode left, ListNode right) {

ListNode dummy = new ListNode(0);

ListNode tail = dummy;

while (left != null && right != null) {

if (left.val < right.val) {

tail.next = left;

left = left.next;

} else {

tail.next = right;

right = right.next;

}

tail = tail.next;

}

if (left != null) {

tail.next = left;

} else {

tail.next = right;

}

return dummy.next;

}

private ListNode findMid(ListNode head) {

if (head.next == null || head == null) {

return head;

}

ListNode slow = head;

ListNode fast = head;

// 先判斷fast 不為空在判斷fast.next不為空 不然容易空指針異常

while (fast.next != null && fast.next.next != null) {

slow = slow.next;

fast = fast.next.next;

}

return slow;

}

16. 92. Reverse Linked List II

https://leetcode.com/problems/reverse-linked-list-ii/#/description\

public ListNode reverseBetween(ListNode head, int m, int n) {

if (head == null || head.next == null) {

return head;

}

int index = 1;

ListNode tail = new ListNode(0);

ListNode dummy = tail;

tail.next = head;

ListNode start = head;

while (index < m) {

tail = start;

start = head.next;

head = head.next;

index++;

}

head = head.next;

ListNode midTail = start;

while (index < n) {

ListNode temp = head.next;

head.next = start;

start = head;

head = temp;

index++;

}

tail.next = start;

midTail.next = head;

return dummy.next;

}

17. 206. Reverse Linked List

https://leetcode.com/problems/reverse-linked-list/#/solutions

public ListNode reverseList(ListNode head) {

/* iterative solution */

ListNode newHead = null;

while (head != null) {

ListNode next = head.next;

head.next = newHead;

newHead = head;

head = next;

}

return newHead;

}

public ListNode reverseList(ListNode head) {

/* recursive solution */

return reverseListInt(head, null);

}

private ListNode reverseListInt(ListNode head, ListNode newHead) {

if (head == null)

return newHead;

ListNode next = head.next;

head.next = newHead;

return reverseListInt(next, head);

}

18. 21. Merge Two Sorted Lists

https://leetcode.com/problems/merge-two-sorted-lists/#/description

http://www.cnblogs.com/EdwardLiu/p/3718025.html

public ListNode mergeTwoLists(ListNode l1, ListNode l2) {

ListNode head = new ListNode(0);

ListNode cur = head;

while (l1 != null && l2 != null) {

if (l1.val < l2.val) {

cur.next = l1;

l1 = l1.next;

}

else {

cur.next = l2;

l2 = l2.next;

}

cur = cur.next;

}

cur.next = (l1 != null) ? l1 : l2;

return head.next;

}

19. 331. Verify Preorder Serialization of a Binary Tree

https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/#/description

https://leetcode.com/problems/verify-preorder-serialization-of-a-binary-tree/#/solutions

出度入度

public boolean isValidSerialization(String preorder) {

String[] nodes = preorder.split(",");

int diff = 1;

for (String node: nodes) {

if (--diff < 0) return false;

if (!node.equals("#")) diff += 2;

}

return diff == 0;

}

用棧

public boolean isValidSerialization(String preorder) {

// using a stack, scan left to right

// case 1: we see a number, just push it to the stack

// case 2: we see #, check if the top of stack is also #

// if so, pop #, pop the number in a while loop, until top of stack is not #

// if not, push it to stack

// in the end, check if stack size is 1, and stack top is #

if (preorder == null) {

return false;

}

Stack<String> st = new Stack<>();

String[] strs = preorder.split(",");

for (int pos = 0; pos < strs.length; pos++) {

String curr = strs[pos];

while (curr.equals("#") && !st.isEmpty() && st.peek().equals(curr)) {

st.pop();

if (st.isEmpty()) {

return false;

}

st.pop();

}

st.push(curr);

}

return st.size() == 1 && st.peek().equals("#");

}

20. 449. Serialize and Deserialize BST

https://leetcode.com/problems/serialize-and-deserialize-bst/#/description

https://leetcode.com/problems/serialize-and-deserialize-bst/#/solutions

public class Codec {

private static final String SEP = ",";

private static final String NULL = "null";

// Encodes a tree to a single string.

public String serialize(TreeNode root) {

StringBuilder sb = new StringBuilder();

if (root == null) return NULL;

//traverse it recursively if you want to, I am doing it iteratively here

Stack<TreeNode> st = new Stack<>();

st.push(root);

while (!st.empty()) {

root = st.pop();

sb.append(root.val).append(SEP);

if (root.right != null) st.push(root.right);

if (root.left != null) st.push(root.left);

}

return sb.toString();

}

// Decodes your encoded data to tree.

// pre-order traversal

public TreeNode deserialize(String data) {

if (data.equals(NULL)) return null;

String[] strs = data.split(SEP);

Queue<Integer> q = new LinkedList<>();

for (String e : strs) {

q.offer(Integer.parseInt(e));

}

return getNode(q);

}

// some notes:

// 5

// 3 6

// 2 7

private TreeNode getNode(Queue<Integer> q) { //q: 5,3,2,6,7

if (q.isEmpty()) return null;

TreeNode root = new TreeNode(q.poll());//root (5)

Queue<Integer> samllerQueue = new LinkedList<>();

while (!q.isEmpty() && q.peek() < root.val) {

samllerQueue.offer(q.poll());

}

//smallerQueue : 3,2 storing elements smaller than 5 (root)

root.left = getNode(samllerQueue);

//q: 6,7 storing elements bigger than 5 (root)

root.right = getNode(q);

return root;

}

21. 491. Increasing Subsequences

https://leetcode.com/problems/increasing-subsequences/#/solutions

public List<List<Integer>> findSubsequences(int[] nums) {

Set<List<Integer>> res= new HashSet<List<Integer>>();

List<Integer> holder = new ArrayList<Integer>();

findSequence(res, holder, 0, nums);

List result = new ArrayList(res);

return result;

}

public void findSequence(Set<List<Integer>> res, List<Integer> holder, int index, int[] nums) {

if (holder.size() >= 2) {

res.add(new ArrayList(holder));

}

for (int i = index; i < nums.length; i++) {

if(holder.size() == 0 || holder.get(holder.size() - 1) <= nums[i]) {

holder.add(nums[i]);

findSequence(res, holder, i + 1, nums);

holder.remove(holder.size() - 1);

}

}

}

22. 547. Friend Circles

https://leetcode.com/problems/friend-circles/#/solutions

相似的題: http://www.cnblogs.com/grandyang/p/5166356.html

dfs

public void dfs(int[][] M, int[] visited, int i) {

for (int j = 0; j < M.length; j++) {

if (M[i][j] == 1 && visited[j] == 0) {

visited[j] = 1;

dfs(M, visited, j);

}

}

}

public int findCircleNum(int[][] M) {

int[] visited = new int[M.length];

int count = 0;

for (int i = 0; i < M.length; i++) {

if (visited[i] == 0) {

dfs(M, visited, i);

count++;

}

}

return count;

}

Bfs

public int findCircleNum(int[][] M) {

int count = 0;

for (int i=0; i<M.length; i++)

if (M[i][i] == 1) { count++; BFS(i, M); }

return count;

}

public void BFS(int student, int[][] M) {

Queue<Integer> queue = new LinkedList<>();

queue.add(student);

while (queue.size() > 0) {

int queueSize = queue.size();

for (int i=0;i<queueSize;i++) {

int j = queue.poll();

M[j][j] = 2; // marks as visited

for (int k=0;k<M[0].length;k++)

if (M[j][k] == 1 && M[k][k] == 1) queue.add(k);

}

}

}

Union find

public class Solution {

class UF {

private int[] id;

private int count;

public UF(int N) {

count = N;

id = new int[N];

for (int i = 0; i < N; i++) {

id[i] = i;

}

}

public int count() {

return count;

}

public int find(int p) {

while (p != id[p]) p = id[p];

return p;

}

public void union(int p, int q) {

int pRoot = find(p);

int qRoot = find(q);

if (pRoot == qRoot) return;

id[pRoot] = qRoot;

count--;

}

}

public int findCircleNum(int[][] M) {

int n = M.length;

UF uf = new UF(n);

for (int i = 0; i < n - 1; i++) {

for (int j = i + 1; j < n; j++) {

if (M[i][j] == 1) uf.union(i, j);

}

}

return uf.count();

}

}

23. 297. Serialize and Deserialize Binary Tree

https://leetcode.com/problems/serialize-and-deserialize-binary-tree/#/description

http://www.cnblogs.com/EdwardLiu/p/5084538.html

public class Codec {

private static final String spliter = ",";

private static final String NN = "X";

// Encodes a tree to a single string.

public String serialize(TreeNode root) {

StringBuilder sb = new StringBuilder();

buildString(root, sb);

return sb.toString();

}

private void buildString(TreeNode node, StringBuilder sb) {

if (node == null) {

sb.append(NN).append(spliter);

} else {

sb.append(node.val).append(spliter);

buildString(node.left, sb);

buildString(node.right,sb);

}

}

// Decodes your encoded data to tree.

public TreeNode deserialize(String data) {

Deque<String> nodes = new LinkedList<>();

nodes.addAll(Arrays.asList(data.split(spliter)));

return buildTree(nodes);

}

private TreeNode buildTree(Deque<String> nodes) {

String val = nodes.remove();

if (val.equals(NN)) return null;

else {

TreeNode node = new TreeNode(Integer.valueOf(val));

node.left = buildTree(nodes);

node.right = buildTree(nodes);

return node;

}

}

}

24. 39. Combination Sum

https://leetcode.com/problems/combination-sum/#/solutions

排序後用的if (i != pos && candidates[i] == candidates[i - 1]) { continue; }

public List<List<Integer>> combinationSum(int[] candidates, int target) {

List<List<Integer>> ans = new ArrayList<>();

List<Integer> list = new ArrayList<>();

Arrays.sort(candidates);

helper(ans, list, candidates, target, 0);

return ans;

}

private void helper(List<List<Integer>> ans, List<Integer> list, int[] candidates, int target, int pos) {

if (target == 0) {

ans.add(new ArrayList(list));

}

for (int i = pos; i < candidates.length; i++) {

if (candidates[i] > target) return;

if (i != pos && candidates[i] == candidates[i - 1]) {

continue;

}

list.add(candidates[i]);

helper(ans, list, candidates, target - candidates[i], i);

list.remove(list.size() - 1);

}

}

用hashSet

public List<List<Integer>> combinationSum(int[] candidates, int target) {

Set<List<Integer>> ans = new HashSet<>();

List<Integer> list = new ArrayList<>();

Arrays.sort(candidates);

helper(ans, list, candidates, target, 0);

List<List<Integer>> res = new ArrayList(ans);

return res;

}

private void helper(Set<List<Integer>> ans, List<Integer> list, int[] candidates, int target, int pos) {

if (target == 0) {

ans.add(new ArrayList(list));

}

for (int i = pos; i < candidates.length; i++) {

if (candidates[i] > target) return;

list.add(candidates[i]);

helper(ans, list, candidates, target - candidates[i], i);

list.remove(list.size() - 1);

}

}

25. 40. Combination Sum II

https://leetcode.com/problems/combination-sum-ii/#/description

public List<List<Integer>> combinationSum2(int[] candidates, int target) {

List<List<Integer>> res = new ArrayList<>();

//List<Integer> list = new ArrayList<Integer>();

if (candidates.length == 0) {

return res;

}

Arrays.sort(candidates);

helper(res, new ArrayList<Integer>(), candidates, target, 0);

return res;

}

private void helper(List<List<Integer>> res, List<Integer> list,

int[] num, int target, int pos) {

if (target == 0) {

res.add(new ArrayList<Integer>(list));

return;

}

for (int i = pos; i < num.length; i++) {

if (num[i] > target) return;

if (i != pos && num[i] == num[i - 1]) {

continue;

}

list.add(num[i]);

helper(res, list, num, target - num[i], i + 1);

list.remove(list.size() - 1);

}

}

26. 46. Permutations

https://leetcode.com/problems/permutations/#/description

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);

}

}

}

27. 47. Permutations II

https://leetcode.com/problems/permutations-ii/#/description

public List<List<Integer>> permuteUnique(int[] nums) {

List<List<Integer>> res = new ArrayList<List<Integer>>();

if(nums==null || nums.length==0) return res;

boolean[] used = new boolean[nums.length];

List<Integer> list = new ArrayList<Integer>();

Arrays.sort(nums);

dfs(nums, used, list, res);

return res;

}

public void dfs(int[] nums, boolean[] used, List<Integer> list, List<List<Integer>> res){

if(list.size()==nums.length){

res.add(new ArrayList<Integer>(list));

return;

}

for(int i=0;i<nums.length;i++){

if(used[i]) continue;

if(i>0 &&nums[i-1]==nums[i] && !used[i-1]) continue;

used[i]=true;

list.add(nums[i]);

dfs(nums,used,list,res);

used[i]=false;

list.remove(list.size()-1);

}

}

}

28. 216. Combination Sum III

https://leetcode.com/problems/combination-sum-iii/#/solutions

public List<List<Integer>> combinationSum3(int k, int n) {

List<List<Integer>> ans = new ArrayList<>();

List<Integer> list = new ArrayList<>();

if (n < k || n >= k * 9 || k < 1) {

//ans.add(list);

return ans;

}

helper(k, n, ans, list, 1);

return ans;

}

private void helper(int k, int n, List<List<Integer>> ans, List<Integer> list, int pos) {

if (list.size() == k && n == 0) {

ans.add(new ArrayList(list));

}

for (int i = pos; i <= 9; i++) {

if (i > n) {

return;

}

list.add(i);

helper(k, n - i, ans, list, i + 1);

list.remove(list.size() - 1);

}

}

29. 377. Combination Sum IV

https://leetcode.com/problems/combination-sum-iv/#/solutions

思路值得借鑒!!!

https://discuss.leetcode.com/topic/52302/1ms-java-dp-solution-with-detailed-explanation

暴力法

public int combinationSum4(int[] nums, int target) {

if (target == 0) {

return 1;

}

int res = 0;

for (int i = 0; i < nums.length; i++) {

if (target >= nums[i]) {

res += combinationSum4(nums, target - nums[i]);

}

}

return res;

}

暴力法轉化為動歸---top down:

private int[] dp;

public int combinationSum4(int[] nums, int target) {

dp = new int[target + 1];

Arrays.fill(dp, -1);

dp[0] = 1;

return helper(nums, target);

}

暴力法轉化為動歸的關鍵所在—用數組保存重復遞歸的函數所以節省了再次遞歸的時間效率, 先寫暴力法、畫圖、在想著怎麽優化時間復雜度, 在重復計算的基礎上優化畫圖—top down

private int helper(int[] nums, int target) {

if (dp[target] != -1) {

return dp[target]; //

}

int res = 0;

for (int i = 0; i < nums.length; i++) {

if (target >= nums[i]) {

res += helper(nums, target - nums[i]);

}

}

dp[target] = res;

return res;

}

用一個for 循環和數組加入了所有的可能因素—是因為第一個for 控制了是的內循環的if 得以展開因此省去重復計算時間bottom up…

動歸----bottom up

public int combinationSum4(int[] nums, int target) {

int[] comb = new int[target + 1];

comb[0] = 1;

for (int i = 1; i < comb.length; i++) {

for (int j = 0; j < nums.length; j++) {

if (i - nums[j] >= 0) {

comb[i] += comb[i - nums[j]];

}

}

}

return comb[target];

}

30. 17. Letter Combinations of a Phone Number

https://leetcode.com/problems/letter-combinations-of-a-phone-number/#/solutions

public class Solution {

private static final String[] KEYS = { "", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz" };

public List<String> letterCombinations(String digits) {

List<String> ret = new LinkedList<String>();

combination("", digits, 0, ret);

return ret;

}

private void combination(String prefix, String digits, int offset, List<String> ret) {

if (offset >= digits.length()) {

ret.add(prefix);

return;

}

String letters = KEYS[(digits.charAt(offset) - ‘0‘)]; //不斷變化的, charAt() – ‘0’表示數組的位置

for (int i = 0; i < letters.length(); i++) {

combination(prefix + letters.charAt(i), digits, offset + 1, ret);

}

}

}

打卡2