九章算法高级班笔记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. 见到数组要想到先排序
相关文章
相关标签/搜索