九章算法高級班筆記1.透析熱門互聯網公司 FollowUp面試題

Minimum Size Subarray Sum cs3k.com

Given an array of n positive integers and a positive integer s, find the minimal length of a subarray of which the sum ≥ s. If there isn’t one, return -1 instead.java

Given the array [2,3,1,2,4,3] and s = 7, the subarray [4,3] has the minimal length under the problem constraint.windows

雙指針問題

  1. 相向型指針
  2. 前向型指針(又叫窗口類型指針)Evernote Snapshot 20171016 135812

 

此題思路 

cs3k.com

開始咱們很容易想到的方法是:數組

1-2

此時的時間複雜度是O(n^3),稍做改動記錄一下sum, 可使時間複雜度變爲O(n^2):數據結構

1-2-2

變成:
1-3wordpress

由於數組裏的全部數值都是正的,因此算數組0到1位的和即s = 0, t= 1時候若是比7小,第一位的和即s = 1, t = 1的時候就不用看了;同理由於0到2位的和比7小,1到2位的和就不用算了:函數

1-4

因此咱們總結了窗口類指針的模板, 重點是根據題目的不一樣改變須要知足的條件。這個優化有如下特色:優化

  1. 優化思想經過兩層for循環而來
  2. 外層指針依然是依次遍歷
  3. 內層指針證實是否須要回退

這種方法的時間複雜度是O(2n)即O(n), 由於每一個元素最多被訪問兩次:
1-5this

固定了i,知道遇到第一個j使得和大於等於s,記錄下來:spa

public class Solution { /** * @param nums: an array of integers * @param s: an integer * @return: an integer representing the minimum size of subarray */ public int minimumSize(int[] nums, int s) { // write your code here int j = 0, i = 0; int sum =0; int ans = Integer.MAX_VALUE; for(i = 0; i < nums.length; i++) { while(j < nums.length && sum < s) { sum += nums[j]; j ++; } if(sum >=s) { ans = Math.min(ans, j - i); } sum -= nums[i]; } if(ans == Integer.MAX_VALUE) ans = -1; return ans; } }

Longest Substring Without Repeating Characters

cs3k.com

Given a string, find the length of the longest substring without repeating characters.指針

For example, the longest substring without repeating letters for 「abcabcbb」 is 「abc」, which the length is 3.

For 「bbbbb」 the longest substring is 「b」, with the length of 1.

用hash記錄下走過的characters

public class Solution { /** * @param s: a string * @return: an integer */ //方法一: public int lengthOfLongestSubstring(String s) { int[] map = new int[256]; // map from character's ASCII to its last occured index int j = 0; int i = 0; int ans = 0; for (i = 0; i < s.length(); i++) { while (j < s.length() && map[s.charAt(j)]==0) { map[s.charAt(j)] = 1; ans = Math.max(ans, j-i + 1); j ++; } map[s.charAt(i)] = 0; } return ans; } }

Minimum Window Substring

cs3k.com

Given a string source and a string target, find the minimum window in source which will contain all the characters in target.

If there is no such window in source that covers all characters in target, return the emtpy string 「」.

If there are multiple such windows, you are guaranteed that there will always be only one unique minimum window in source.

Clarification

Should the characters in minimum window has the same order in target?

Not necessary.

Example

For source = 「ADOBECODEBANC」, target = 「ABC」, the minimum window is 「BANC」

public class Solution { //方法一: int initTargetHash(int []targethash, String Target) { int targetnum =0 ; for (char ch : Target.toCharArray()) { targetnum++; targethash[ch]++; } return targetnum; } boolean valid(int []sourcehash, int []targethash) { for(int i = 0; i < 256; i++) { if(targethash[i] > sourcehash[i]) return false; } return true; } public String minWindow(String Source, String Target) { // queueing the position that matches the char in T int ans = Integer.MAX_VALUE; String minStr = ""; int[] sourcehash = new int[256]; int[] targethash = new int[256]; initTargetHash(targethash, Target); int j = 0, i = 0; for(i = 0; i < Source.length(); i++) { while( !valid(sourcehash, targethash) && j < Source.length() ) { sourcehash[Source.charAt(j)]++; j++; } if(valid(sourcehash, targethash) ){ if(ans > j - i ) { ans = Math.min(ans, j - i ); minStr = Source.substring(i, j ); } } sourcehash[Source.charAt(i)]--; } return minStr; } }

其中valid函數能夠優化,即加上一個count使得時間上O(256n)變成O(n);

我考慮用兩個hashset:一個target_hash, 一個source_hash,實現下看看。

Longest Substring with At Most K Distinct Characters

Given a string s, find the length of the longest substring T that contains at most k distinct characters.

For example, Given s = 「eceba」, k = 3,

T is 「eceb」 which its length is 4.

j不用退的狀況,考慮咱們的模板。

public class Solution { /** * @param s : A string * @return : The length of the longest substring * that contains at most k distinct characters. */ public int lengthOfLongestSubstringKDistinct(String s, int k) { // write your code here int maxLen = 0; // Key: letter; value: the number of occurrences. Map<Character, Integer> map = new HashMap<Character, Integer>(); int i, j = 0; char c; for (i = 0; i < s.length(); i++) { while (j < s.length()) { c = s.charAt(j); if (map.containsKey(c)) { map.put(c, map.get(c) + 1); } else { if(map.size() ==k) break; map.put(c, 1); } j++; } maxLen = Math.max(maxLen, j - i); c = s.charAt(i); if(map.containsKey(c)){ int count = map.get(c); if (count > 1) { map.put(c, count - 1); } else { map.remove(c); } } } return maxLen; } }

作題及複習方法

cs3k.com

按期停下腳步,整理本身作過的題目,對本身提三個問題:

  1. 屬於哪一類?是動規,哪一種動規?揹包?是雙指針,是哪一種雙指針?歸類到很細分的題目類型中2.同類的題目有什麼類似之處?題目的問法啊?全部用dfs啊,最短用bfs啊作題的感受?

    bfs一層一層啊,動規也是一層一層啊

    3.他們思考的思路是怎麼樣的?

葵花寶典四決

  1. 課前預習課以前瀏覽一遍當前課須要講的內容。最好是本身思考一下每道題的解法,若是時間不夠,能夠瀏覽一下每一個題目的題意。這個很是有助於上課理解。
  2. 課中筆記
  3. 下課冥想
  4. 課後做業做業題先本身想,想不出來看筆記,實在不行看code答案

Kth Smallest Number in Sorted Matrix

cs3k.com

Find the kth smallest number in at row and column sorted matrix.

Example

Given k = 4 and a matrix:

[

[1 ,5 ,7],

[3 ,7 ,8],

[4 ,8 ,9],

]

return 5

總結:見到集合求MIN/MAX,就要想到堆

堆得push和pop是log(n)時間的操做,top即求min/max是O(1)時間的操做

堆有不少種實現方式,priority_queue是經常使用的一種,還有斐波那契堆之類的。

class Pair {
    public int x, y, val; public Pair(int x, int y, int val) { this.x = x; this.y = y; this.val = val; } } class PairComparator implements Comparator { public int compare(Pair a, Pair b) { return a.val - b.val; } } public class Solution { /** * @param matrix: a matrix of integers * @param k: an integer * @return: the kth smallest number in the matrix */ public int kthSmallest(int[][] matrix, int k) { // write your code here int[] dx = new int[]{0, 1}; int[] dy = new int[]{1, 0}; int n = matrix.length; int m = matrix[0].length; boolean[][] hash = new boolean[n][m]; PriorityQueue minHeap = new PriorityQueue(k, new PairComparator()); minHeap.add(new Pair(0, 0, matrix[0][0])); for(int i = 0; i < k - 1; i ++){ Pair cur = minHeap.poll(); for(int j = 0; j < 2; j ++){ int next_x = cur.x + dx[j]; int next_y = cur.y + dy[j]; Pair next_Pair = new Pair(next_x, next_y, 0); if(next_x < n && next_y < m && !hash[next_x][next_y]){ hash[next_x][next_y] = true; next_Pair.val = matrix[next_x][next_y]; minHeap.add(next_Pair); } } } return minHeap.peek().val; } } 

Kth Largest in N Arrays

cs3k.com

You can swap elements in the array

Example

In n=2 arrays [[9,3,2,4,7],[1,2,3,4,8]], the 3rd largest element is 7.

In n=2 arrays [[9,3,2,4,8],[1,2,3,4,2]], the 1st largest element is 9, 2nd largest element is 8, 3rd largest element is 7 and etc.

總結:見到數組先排序

用什麼數據結構?

方法:

  1. 把N個數組先排序
  2. 排序事後把每一個數組最大的數字放入堆裏面
  3. 而後堆裏面只維護前N個元素
  4. 堆pop k次獲得答案。
  5. 時間複雜度N*Len*Log(len)+K*logN (len 是平均每一個數組的長度)
import java.util.Comparator; import java.util.PriorityQueue; import java.util.Queue; class Node { public int value, from_id, index; public Node(int _v, int _id, int _i) { this.value = _v; this.from_id = _id; this.index = _i; } } public class Solution { /** * @param arrays a list of array * @param k an integer * @return an integer, K-th largest element in N arrays */ public int KthInArrays(int[][] arrays, int k) { // Write your code here Queue queue = new PriorityQueue(k, new Comparator() { public int compare(Node o1, Node o2) { if (o1.value > o2.value) return -1; else if (o1.value < o2.value) return 1; else return 0; } }); int n = arrays.length; int i; for (i = 0; i < n; ++i) { Arrays.sort(arrays[i]); if (arrays[i].length > 0) { int from_id = i; int index = arrays[i].length - 1; int value = arrays[i][index]; queue.add(new Node(value, from_id, index)); } } for (i = 0; i < k; ++i) { Node temp = queue.poll(); int from_id = temp.from_id; int index = temp.index; int value = temp.value; if (i == k - 1) return value; if (index > 0) { index --; value = arrays[from_id][index]; queue.add(new Node(value, from_id, index)); } } return -1; } }

Kth Smallest Sum In Two Sorted Arrays

cs3k.com

Given two integer arrays sorted in ascending order and an integer k. Define sum = a + b, where a is an element from the first array and b is an element from the second one. Find the kth smallest sum out of all possible sums.

Given [1, 7, 11] and [2, 4, 6].

For k = 3, return 7.

For k = 4, return 9.

For k = 8, return 15.

class Pair {
    public int x, y, sum; public Pair(int x, int y, int val) { this.x = x; this.y = y; this.sum = val; } } class PairComparator implements Comparator { public int compare(Pair a, Pair b) { return a.sum - b.sum; } } public class Solution { /** * @param A an integer arrays sorted in ascending order * @param B an integer arrays sorted in ascending order * @param k an integer * @return an integer */ public int kthSmallestSum(int[] A, int[] B, int k) { int[] dx = new int[]{0, 1}; int[] dy = new int[]{1, 0}; boolean[][] hash = new boolean[A.length][B.length]; PriorityQueue minHeap = new PriorityQueue(k, new PairComparator()); minHeap.add(new Pair(0, 0, A[0] + B[0])); for(int i = 0; i < k - 1; i ++){ Pair cur = minHeap.poll(); for(int j = 0; j < 2; j ++){ int next_x = cur.x + dx[j]; int next_y = cur.y + dy[j]; Pair next_Pair = new Pair(next_x, next_y, 0); if(next_x < A.length && next_y < B.length && !hash[next_x][next_y]){ hash[next_x][next_y] = true; next_Pair.sum = A[next_x] + B[next_y]; minHeap.add(next_Pair); } } } return minHeap.peek().sum; } }

三道題小總結

三道題類似點:

求矩陣/數組的第k大

能夠總結的規律

  1. 見到須要維護一個集合的最小值/最大值的時候要想到用堆
  2. 第k小的元素,Heap用來維護當前候選集合。
  3. 見到數組要想到先排序

怎麼解決不會作follow up問題

cs3k.com

1.按期整理本身作過的題目,Note

2.學會反思:

它屬於哪一類?(歸類)

和它同類的題目有什麼類似之處?(集體特徵)

這些題目思考的思路是怎麼樣的?(這個題屬於哪一類)

 

本節要點概覽:

  1. 窗口問題想兩個指針,兩個指針中j不用回退想for while模板
  2. 看出現次數和重複的時候,能夠用set, map和數組,還能夠加count記錄在案個數
  3. 見到須要維護一個集合的最小值/最大值的時候要想到用堆
  4. 第k小的元素,Heap用來維護當前候選集合。
  5. 見到數組要想到先排序
相關文章
相關標籤/搜索