• 九章算法强化班ladder题目梳理


    1 - Follow up in Code Interview

    kth-smallest-number-in-sorted-matrix

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

    [
    [1 ,5 ,7],
    [3 ,7 ,8],
    [4 ,8 ,9],
    ]

    注意点:

    • Comparator<Pair>的实现
    • PriorityQueue poll add
     1 import java.util.*;
     2 
     3 class Pair{
     4     public int x, y, val;
     5     public Pair(int x, int y, int val){
     6         this.x = x;
     7         this.y = y;
     8         this.val = val;
     9     }
    10 }
    11 
    12 class PairComparator implements Comparator<Pair> {
    13     public int compare(Pair a, Pair b){
    14         return a.val - b.val;
    15     }
    16 }
    17 
    18 public class Solution {
    19     /**
    20      * @param matrix: a matrix of integers
    21      * @param k: an integer
    22      * @return: the kth smallest number in the matrix
    23      */
    24     public int kthSmallest(int[][] matrix, int k) {
    25         // write your code here
    26         int[] dx = {0, 1};
    27         int[] dy = {1, 0};
    28         int m = matrix.length;
    29         int n = matrix[0].length;
    30         boolean[][] visited = new boolean[m][n];
    31         PriorityQueue<Pair> pq = new PriorityQueue<>(k, new PairComparator());
    32         pq.add(new Pair(0, 0, matrix[0][0]));
    33 
    34         for (int i = 0; i < k - 1; i++){
    35             Pair cur = pq.poll();
    36             for (int j = 0; j < 2; j++){
    37                 int x = cur.x + dx[j];
    38                 int y = cur.y + dy[j];
    39                 if (x < m && y < n && !visited[x][y]){
    40                     pq.add(new Pair(x, y, matrix[x][y]));
    41                     visited[x][y] = true;
    42 
    43                 }
    44             }
    45         }
    46         return pq.peek().val;
    47     }
    48 }
    View Code

    minimum-size-subarray-sum

    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.

    注意点:

    • 对于当前i,找到j使得i~j>=s,对于下一个i,j不需要回退到i(题目性质),所以可以在O(n)时间复杂度内得到解
     1 public class Solution {
     2     /**
     3      * @param nums: an array of integers
     4      * @param s: an integer
     5      * @return: an integer representing the minimum size of subarray
     6      */
     7     public int minimumSize(int[] nums, int s) {
     8         // write your code here
     9         if (nums == null || nums.length == 0) return -1;
    10         int result = -1;
    11         int j = 0;
    12         int sum = 0;
    13         for (int i = 0; i < nums.length; i++){
    14             boolean flag = false;
    15             if (i > 0){
    16                 sum -= nums[i - 1];
    17                 flag = true;
    18             }
    19             while (j < nums.length){
    20                 if (!flag) {
    21                     sum += nums[j];
    22                 }
    23                 else {
    24                     flag = false;
    25                 }
    26                 if (sum >= s){
    27                     if (result == -1 || j - i + 1 < result){
    28                         result = j - i + 1;
    29                     }
    30                     break;
    31                 }
    32                 j++;
    33             }
    34         }
    35         return result;
    36     }
    37 }
    View Code

    longest-substring-without-repeating-characters

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

    注意点:

    • 使用一个map记录各个字母出现次数
     1 import java.util.*;
     2 public class Solution {
     3     /**
     4      * @param s: a string
     5      * @return: an integer
     6      */
     7     public int lengthOfLongestSubstring(String s) {
     8         // write your code here
     9         int result = 0;
    10         if (s == null || s.length() == 0){
    11             return result;
    12         }
    13         Map<Character, Integer> map = new HashMap<>();
    14         int j = 0;
    15         for (int i = 0; i < s.length(); i++){
    16             if (i > 0){
    17                 map.put(s.charAt(i - 1), map.get(s.charAt(i - 1)) - 1);
    18                 if (map.get(s.charAt(i - 1)) == 0){
    19                     map.remove(s.charAt(i - 1));
    20                 }
    21             }
    22             while(j < s.length()){
    23                 if (map.containsKey(s.charAt(j))){
    24                     break;
    25                 }
    26                 else {
    27                     map.put(s.charAt(j), 1);
    28                     if (map.entrySet().size() > result){
    29                         result = map.entrySet().size();
    30                     }
    31                     j++;
    32                 }
    33             }
    34         }
    35         return result;
    36     }
    37 }
    View Code

    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.

    注意:

    • map.entrySet().size() > k 判断键的个数也可以用keySet
     1 public class Solution {
     2     /**
     3      * @param s : A string
     4      * @return : The length of the longest substring
     5      *           that contains at most k distinct characters.
     6      */
     7     public int lengthOfLongestSubstringKDistinct(String s, int k) {
     8         // write your code here
     9         int result = 0;
    10         if (s == null || s.length() == 0){
    11             return result;
    12         }
    13         Map<Character, Integer> map = new HashMap<>();a
    14         int j = 0;
    15         for (int i = 0; i < s.length(); i++){
    16             boolean flag = false;
    17             if (i > 0){
    18                 map.put(s.charAt(i - 1), map.get(s.charAt(i - 1)) - 1);
    19                 if (map.get(s.charAt(i - 1)) == 0){
    20                     map.remove(s.charAt(i - 1));
    21                 }
    22                 flag = true;
    23             }
    24             while(j < s.length()){
    25                 if(!flag){
    26                     if (map.containsKey(s.charAt(j))){
    27                         map.put(s.charAt(j), map.get(s.charAt(j)) + 1);
    28                     }
    29                     else{
    30                         map.put(s.charAt(j), 1);
    31                     }
    32                 }
    33                 else {
    34                     flag = false;
    35                 }
    36                 if (map.entrySet().size() > k){
    37                     break;
    38                 }
    39                 else {
    40                     if (j - i + 1 > result){
    41                         result = j - i + 1;
    42                     }
    43                     j++;
    44                 }
    45             }
    46         }
    47         return result;
    48     }
    49 }
    View Code

    kth-smallest-sum-in-two-sorted-arrays

    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.

    注意点:

    • 把这两个数组的和,看成一个矩阵,就变成kth-smallest-number-in-sorted-matrix了
     1 import java.util.*;
     2 
     3 class Pair{
     4     public int x, y, val;
     5     public Pair(int x, int y, int val){
     6         this.x = x;
     7         this.y = y;
     8         this.val = val;
     9     }
    10 }
    11 
    12 class PairComparator implements Comparator<Pair>{
    13     public int compare(Pair a, Pair b){
    14         return a.val - b.val;
    15     }
    16 }
    17 
    18 
    19 public class Solution {
    20     /**
    21      * @param A an integer arrays sorted in ascending order
    22      * @param B an integer arrays sorted in ascending order
    23      * @param k an integer
    24      * @return an integer
    25      */
    26     public int kthSmallestSum(int[] A, int[] B, int k) {
    27         // Write your code here
    28         int[] dx = {0, 1};
    29         int[] dy = {1, 0};
    30         int m = A.length;
    31         int n = B.length;
    32         boolean[][] visited = new boolean[m][n];
    33         PriorityQueue<Pair> pq = new PriorityQueue<>(k, new PairComparator());
    34         pq.add(new Pair(0, 0, A[0] + B[0]));
    35         for (int i = 0; i < k - 1; i++){
    36             Pair cur = pq.poll();
    37             for(int j = 0; j < 2; j++){
    38                 int x = cur.x + dx[j];
    39                 int y = cur.y + dy[j];
    40                 if (x < m && y < n && !visited[x][y]){
    41                     visited[x][y] = true;
    42                     pq.add(new Pair(x, y, A[x] + B[y]));
    43                 }
    44             }
    45         }
    46         return pq.peek().val;
    47     }
    48 }
    View Code

    kth-largest-in-n-arrays

    Find K-th largest element in N arrays.

    N个数组找第K大

     1 import java.util.*;
     2 
     3 class Item{
     4     public int val, index, array;
     5     public Item(int val, int index, int array){
     6         this.val = val;
     7         this.index = index;
     8         this.array = array;
     9     }
    10 }
    11 
    12 class ItemComparator implements Comparator<Item>{
    13     public int compare(Item a, Item b){
    14         return b.val - a.val;
    15     }
    16 }
    17 
    18 public class Solution {
    19     /**
    20      * @param arrays a list of array
    21      * @param k an integer
    22      * @return an integer, K-th largest element in N arrays
    23      */
    24     public int KthInArrays(int[][] arrays, int k) {
    25         // Write your code here
    26         PriorityQueue<Item> pq = new PriorityQueue<>(k, new ItemComparator());
    27         for (int i = 0; i < arrays.length; i++){
    28             Arrays.sort(arrays[i]);
    29             if (arrays[i].length > 0){
    30                 pq.add(new Item(arrays[i][arrays[i].length - 1], arrays[i].length - 1, i));
    31             }
    32         }
    33         for (int i = 0; i < k - 1; i++){
    34             Item item = pq.poll();
    35             if (item.index > 0){
    36                 pq.offer(new Item(arrays[item.array][item.index - 1], item.index - 1, item.array));
    37             }
    38         }
    39         return pq.peek().val;
    40     }
    41 }
    View Code

    two-sum-less-than-or-equal-to-target

    Given an array of integers, find how many pairs in the array such that their sum is less than or equal to a specific target number. Please return the number of pairs.

    找小于等于target的pairs数

    注意点:

    • 先排序
    • 两根指针移动时,可以根据两根指针的和,得到一个范围的解
     1 import java.util.*;
     2 public class Solution {
     3     /**
     4      * @param nums an array of integer
     5      * @param target an integer
     6      * @return an integer
     7      */
     8     public int twoSum5(int[] nums, int target) {
     9         // Write your code here
    10         int result = 0;
    11         if (nums == null || nums.length < 2){
    12             return result;
    13         }
    14         Arrays.sort(nums);
    15         int left = 0;
    16         int right = nums.length - 1;
    17         while (left < right){
    18             if (nums[left] + nums[right] <= target){
    19                 result += right - left;
    20                 left++;
    21             }
    22             else{
    23                 right--;
    24             }
    25         }
    26         return result;
    27     }
    28 }
    View Code

    triangle-count

    Given an array of integers, how many three numbers can be found in the array, so that we can build an triangle whose three edges length is the three numbers that we find?

    上一题的变形题,先排序,固定最后一个元素,找前面大于target的pairs数

     1 import java.util.*;
     2 public class Solution {
     3     /**
     4      * @param S: A list of integers
     5      * @return: An integer
     6      */
     7     public int triangleCount(int S[]) {
     8         // write your code here
     9         Arrays.sort(S);
    10         int result = 0;
    11         for(int i = S.length - 1; i > 1; i--){
    12             result += twoSum(S, 0, i - 1, S[i]);
    13         }
    14         return result;
    15     }
    16     
    17     private int twoSum(int S[], int start, int end, int target){
    18         int result = 0;
    19         while (start < end){
    20             if (S[start] + S[end] > target){
    21                 result += end - start;
    22                 end--;
    23             }
    24             else{
    25                 start++;
    26             }
    27         }
    28         return result;
    29     }
    30 }
    View Code

    minimum-window-substring

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

    拥有target串所有字母(相同字母个数>=)的source中最靠近开头的串。

    两次遍历,先找结尾,再找开头

     1 import java.util.*;
     2 
     3 public class Solution {
     4     /**
     5      * @param source: A string
     6      * @param target: A string
     7      * @return: A string denote the minimum window
     8      *          Return "" if there is no such a string
     9      */
    10     public String minWindow(String source, String target) {
    11         // write your code
    12         if (source.length() == 0 || target.length() == 0) return "";
    13         int startIndex = 0;
    14         int endIndex = 0;
    15         Map<Character, Integer> targetMap = new HashMap<>();
    16         Map<Character, Integer> sourceMap = new HashMap<>();
    17         for (int i = 0; i < target.length(); i++){
    18             if (!targetMap.containsKey(target.charAt(i))){
    19                 targetMap.put(target.charAt(i), 1);
    20             }
    21             else{
    22                 targetMap.put(target.charAt(i), targetMap.get(target.charAt(i)) + 1);
    23             }
    24         }
    25         while(endIndex < source.length()){
    26             if (!sourceMap.containsKey(source.charAt(endIndex))){
    27                 sourceMap.put(source.charAt(endIndex), 1);
    28             }
    29             else{
    30                 sourceMap.put(source.charAt(endIndex), sourceMap.get(source.charAt(endIndex)) + 1);
    31             }
    32             if (testHash(sourceMap, targetMap)){
    33                 break;
    34             }
    35             endIndex++;
    36         }
    37         if (endIndex == source.length()){
    38             return "";
    39         }
    40         while(startIndex <= endIndex){
    41             sourceMap.put(source.charAt(startIndex), sourceMap.get(source.charAt(startIndex)) - 1);
    42             if (sourceMap.get(source.charAt(startIndex)) == 0){
    43                 sourceMap.remove(source.charAt(startIndex));
    44             }
    45             if (!testHash(sourceMap, targetMap)){
    46                 break;
    47             }
    48             startIndex++;
    49         }
    50         return source.substring(startIndex, endIndex + 1);
    51     }
    52     
    53     private boolean testHash(Map<Character, Integer> sourceMap, Map<Character, Integer> targetMap){
    54         for (Character key : targetMap.keySet()){
    55             if (!sourceMap.containsKey(key) || sourceMap.get(key) < targetMap.get(key)) {
    56                 return false;
    57             }
    58         }
    59         return true;
    60     }
    61 }
    View Code

    kth-smallest-numbers-in-unsorted-array

    Find the kth smallest numbers in an unsorted integer array.

    使用quickSelect算法:

    • i <= j; nums[x] > pivot
    • j - start >= k - 1; 第k个点落入0~j之间;quickSelect(nums, start, j, k);
    • i - start <= k - 1; 第k个点落入i~end之间;quickSelect(nums, i, end, k - i + start);
    • 第k个点落入j~i之间;返回nums[j + 1];

    关于partition的理解:

    • partition之后,<=pivot的在左边,>=pivot的在右边,并不存在左右明确的分界线
    • 只能保证j及其左边<=pivot,i及其右边>=pivot。可以配合k使得搜索区域减小一半
     1 class Solution {
     2     /*
     3      * @param k an integer
     4      * @param nums an integer array
     5      * @return kth smallest element
     6      */
     7     public int kthSmallest(int k, int[] nums) {
     8         // write your code here
     9         return quickSelect(nums, 0, nums.length - 1, k);
    10     }
    11 
    12     private int quickSelect(int[] nums, int start, int end, int k){
    13         if (start >= end){
    14             return nums[start];         //区间只有一个数,直接返回
    15         }
    16         int pivot = nums[(start + end) / 2];
    17         int i = start;
    18         int j = end;
    19         while(i <= j){                           //i<=j,有等号
    20             while(i <= j && nums[i] < pivot){         //和pivot比较没有等号
    21                 i++;
    22             }
    23             while(i <= j && nums[j] > pivot){
    24                 j--;
    25             }
    26             if(i <= j){
    27                 int tmp = nums[i];
    28                 nums[i] = nums[j];
    29                 nums[j] = tmp;
    30                 i++;                             //两个同时++ --
    31                 j--;
    32             }
    33         }
    34         if (j - start >= k - 1){              //答案落在0~j区间
    35             return quickSelect(nums, start, j, k);
    36         }
    37         else if (i - start <= k - 1){                //答案落在i~end区间,注意k
    38             return quickSelect(nums, i, end, k - i + start);
    39         }
    40         else {
    41             return nums[j + 1];             //j和i中间隔了一个,它恰好是答案
    42         }
    43     }
    44 }
    View Code

    kth-largest-element

    Find K-th largest element in an array.

    找第k大,与上题思路一样。

     1 class Solution {
     2     /*
     3      * @param k : description of k
     4      * @param nums : array of nums
     5      * @return: description of return
     6      */
     7     public int kthLargestElement(int k, int[] nums) {
     8         // write your code here
     9         return quickSelect(nums, 0, nums.length - 1, k);
    10     }
    11 
    12     private int quickSelect(int[] nums, int start, int end, int k){
    13         if (start >= end){
    14             return nums[start];
    15         }
    16         int pivot = nums[(start + end) / 2];
    17         int i = start;
    18         int j = end;
    19         while (i <= j){
    20             while (i <= j && nums[i] > pivot){
    21                 i++;
    22             }
    23             while (i <= j && nums[j] < pivot){
    24                 j--;
    25             }
    26             if (i <= j){
    27                 int tmp = nums[i];
    28                 nums[i] = nums[j];
    29                 nums[j] = tmp;
    30                 i++;
    31                 j--;
    32             }
    33         }
    34         if(j - start >= k - 1){
    35             return quickSelect(nums, start, j, k);
    36         }
    37         else if(i - start <= k - 1){
    38             return quickSelect(nums, i, end, k - i + start);
    39         }
    40         else{
    41             return nums[j + 1];
    42         }
    43     }
    44 };
    View Code

    2 - Data Structure I

    connecting-graph

    Given n nodes in a graph labeled from 1 to n. There is no edges in the graph at beginning.

    You need to support the following method:
    1. connect(a, b), add an edge to connect node a and node b. 2.query(a, b)`, check if two nodes are connected

    并查集简单应用,father[a] == a是这个类别的队长

     1 public class ConnectingGraph {
     2 
     3     private int[] father = null;
     4 
     5     public ConnectingGraph(int n) {
     6         // initialize your data structure here.
     7         father = new int[n];
     8         for(int i = 0; i < n; i++){
     9             father[i] = i;
    10         }
    11     }
    12 
    13     private int find(int a){
    14         if (father[a] == a){
    15             return a;
    16         }
    17         int result = find(father[a]);
    18         father[a] = result;
    19         return result;
    20     }
    21 
    22     public void connect(int a, int b) {
    23         // Write your code here
    24         int a_f = find(a - 1);
    25         int b_f = find(b - 1);
    26         father[a_f] = b_f;
    27 
    28     }
    29 
    30     public boolean  query(int a, int b) {
    31         // Write your code here
    32         int a_f = find(a - 1);
    33         int b_f = find(b - 1);
    34         return a_f == b_f;
    35     }
    36 }
    View Code

    connecting-graph-ii

    Given n nodes in a graph labeled from 1 to n. There is no edges in the graph at beginning.

    You need to support the following method:
    1. connect(a, b), an edge to connect node a and node b
    2. query(a), Returns the number of connected component nodes which include node a.

    返回当前节点所在联通块的节点数。

    队长节点保存节点数,取负数作为标记。

    connect时需要判断,以免错误覆盖

     1 class Pair{
     2     public int index = 0;
     3     public int result = 0;
     4 
     5     public Pair(int index, int result){
     6         this.index = index;
     7         this.result = result;
     8     }
     9 }
    10 
    11 public class ConnectingGraph2 {
    12 
    13     private int[] father = null;
    14 
    15     public ConnectingGraph2(int n) {
    16         // initialize your data structure here.
    17         father = new int[n];
    18         for(int i = 0; i < n; i++){
    19             father[i] = -1;
    20         }
    21     }
    22 
    23     private Pair find(int a){
    24         if (father[a] < 0){
    25             return new Pair(a, father[a]);
    26         }
    27         Pair r = find(father[a]);
    28         father[a] = r.index;
    29         return r;
    30     }
    31 
    32     public void connect(int a, int b) {
    33         // Write your code here
    34         Pair a_f = find(a - 1);
    35         Pair b_f = find(b - 1);
    36         if (a_f.index != b_f.index){
    37             father[a_f.index] = a_f.result + b_f.result;
    38             father[b_f.index] = a_f.index;
    39         }
    40         // System.out.println(Arrays.toString(father));
    41     }
    42 
    43     public int query(int a) {
    44         // Write your code here
    45         return -find(a - 1).result;
    46     }
    47 }
    View Code

    connecting-graph-iii

    Given n nodes in a graph labeled from 1 to n. There is no edges in the graph at beginning.

    You need to support the following method:
    1. connect(a, b), an edge to connect node a and node b
    2. query(), Returns the number of connected component in the graph

    返回联通块总数,维持一个全局的count即可。

     1 public class ConnectingGraph3 {
     2 
     3     private int[] father = null;
     4     private int count = 0;
     5 
     6     public ConnectingGraph3(int n) {
     7         // initialize your data structure here.
     8         this.count = n;
     9         father = new int[n];
    10         for(int i = 0; i < n; i++){
    11             father[i] = i;
    12         }
    13     }
    14 
    15     private int find(int a){
    16         if (father[a] == a){
    17             return a;
    18         }
    19         int result = find(father[a]);
    20         father[a] = result;
    21         return result;
    22     }
    23 
    24     public void connect(int a, int b) {
    25         // Write your code here
    26         int a_f = find(a - 1);
    27         int b_f = find(b - 1);
    28         if (a_f != b_f){
    29             count--;
    30         }
    31         father[a_f] = b_f;
    32     }
    33 
    34     public int query() {
    35         // Write your code here
    36         return count;
    37     }
    38 }
    View Code
  • 相关阅读:
    制作一个漂亮的表格
    模版语言
    Django 学习
    linux系统服务名称
    CentOS下netstat + awk 查看tcp的网络连接状态
    Python的MySQLdb模块安装
    shellinabox安装
    堡垒机 paramiko 自动登陆代码
    堡垒机 paramiko代码
    Paramiko 模块使用
  • 原文地址:https://www.cnblogs.com/zcy-backend/p/6950730.html
Copyright © 2020-2023  润新知