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
開始咱們很容易想到的方法是:數組
此時的時間複雜度是O(n^3),稍做改動記錄一下sum, 可使時間複雜度變爲O(n^2):數據結構
變成:
wordpress
由於數組裏的全部數值都是正的,因此算數組0到1位的和即s = 0, t= 1時候若是比7小,第一位的和即s = 1, t = 1的時候就不用看了;同理由於0到2位的和比7小,1到2位的和就不用算了:函數
因此咱們總結了窗口類指針的模板, 重點是根據題目的不一樣改變須要知足的條件。這個優化有如下特色:優化
這種方法的時間複雜度是O(2n)即O(n), 由於每一個元素最多被訪問兩次:
this
固定了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; } }
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; } }
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,實現下看看。
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; } }
bfs一層一層啊,動規也是一層一層啊
3.他們思考的思路是怎麼樣的?
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
堆得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; } }
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.
堆
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; } }
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.按期整理本身作過的題目,Note
2.學會反思:
它屬於哪一類?(歸類)
和它同類的題目有什麼類似之處?(集體特徵)
這些題目思考的思路是怎麼樣的?(這個題屬於哪一類)
本節要點概覽: