【Weekly】No.180

C_01 矩阵中的幸运数

Given a m * n matrix of distinct numbers, return all lucky numbers in the matrix in any order.

A lucky number is an element of the matrix such that it is the minimum element in its row and maximum in its column.

Example 1:
Input: matrix = [[3,7,8],[9,11,13],[15,16,17]]
Output: [15]
Explanation: 15 is the only lucky number since it is the minimum in its row and the maximum in its column

方法一:模拟

public List<Integer> luckyNumbers (int[][] matrix) {
  int m = matrix.length;
  int n = matrix[0].length;
  LinkedList<Integer> res = new LinkedList<>();
  
  for (int i = 0; i < m; i++) {
    for (int j = 0; j < n; j++) {
      int min = matrix[i][j];
      boolean minR = true;
      boolean maxC = true;
      //检查行,
      for (int c = 0; c < n; c++) {
        if (matrix[i][c] < min) {
          minR = false;
          break;
        }
      }
      //检查列
      for (int r = 0; r < m; r++) {
        if (matrix[r][j] > min)
          maxC = false;
      }
      if (maxC && minR)
        res.add(min);
      }
  }
  return res;
}

复杂度分析

  • 时间复杂度: O ( n × m ) O(n × m)
  • 空间复杂度: O ( 1 ) O(1)

B_02 设计一个支持增量操作的栈

请你设计一个支持下述操作的栈。实现自定义栈类 CustomStack :

CustomStack(int maxSize):用 maxSize 初始化对象,maxSize 是栈中最多能容纳的元素数量,栈在增长到 maxSize 之后则不支持 push 操作。
void push(int x):如果栈还未增长到 maxSize ,就将 x 添加到栈顶。
int pop():返回栈顶的值,或栈为空时返回 -1void inc(int k, int val):栈底的 k 个元素的值都增加 val 。如果栈中元素总数小于 k ,则栈中的所有元素都增加 val 。

方法一:模拟

class CustomStack {
  int[] stack;
  int pTop;
  int size;
  int max;
  public CustomStack(int maxSize) {
    stack = new int[maxSize];
    max = maxSize;
    size = 0;
    pTop = -1;
  }

  public void push(int x) {
    if (size == max) {
      return;
    }
    stack[++pTop] = x;
    size++;
  }

  public int pop() {
    if (size == 0) {
      return -1;
    }
    size--;
    return stack[pTop--];
  }

  public void increment(int k, int val) {
  	int bound = Math.min(size, k);
  	for (int i = 0; i < bound; i++) {
        stack[i] += val;
    }
  }
}

B_03 将二叉搜索树变平衡

Given a binary search tree, return a balanced binary search tree with the same node values.

A binary search tree is balanced if and only if the depth of the two subtrees of every node never differ by more than 1.

If there is more than one answer, return any of them.

Input: root = [1,null,2,null,3,null,4,null,null]
Output: [2,1,3,null,null,null,4]
Explanation: This is not the only correct answer, [3,1,4,null,2,null,null] is also correct.

方法一:dfs + 中序遍历

List<Integer> nums;
public TreeNode balanceBST(TreeNode root) {
  nums = new ArrayList<>();
  inOrder(root);
  return dfs(0, nums.size());
}
//构造
TreeNode dfs(int l, int r) {
  TreeNode root = null;
  if (l == r) {
    return root;
  }
  int mid = (l + r) >>> 1;
  root = new TreeNode(nums.get(mid));
  root.left =  dfs(l, mid);
  root.right = dfs(mid + 1, r);
  return root;
}
//得到有序数组
void inOrder(TreeNode root) {
  if (root == null)
    return;
  inOrder(root.left);
  nums.add(root.val);
  inOrder(root.right);
}

复杂度分析

  • 时间复杂度: O ( n ) O(n)
  • 空间复杂度: O ( n ) O(n)

A_04 最大的团队表现值(没 ac)

There are n engineers numbered from 1 to n and two arrays: speed and efficiency, where speed[i] and efficiency[i] represent the speed and efficiency for the i-th engineer respectively. Return the maximum performance of a team composed of at most k engineers, since the answer can be a huge number, return this modulo 10^9 + 7.

The performance of a team is the sum of their engineers’ speeds multiplied by the minimum efficiency among their engineers.

输入:n = 6, speed = [2,10,3,1,5,8], efficiency = [5,4,3,9,7,2], k = 2
输出:60
解释:
我们选择工程师 2(speed=10 且 efficiency=4)和工程师 5(speed=5 且 efficiency=7)。
他们的团队表现值为 performance = (10 + 5) * min(4, 7) = 60

方法一:错误解法

final static int MOD = 10^9 + 7;
public int maxPerformance(int n, int[] speed, int[] e, int k) {

  PriorityQueue<Pair> pQ = new PriorityQueue<>((s1, s2) -> s2.speed - s1.speed);

  for (int i = 0; i < n; i++) {
    pQ.add(new Pair(speed[i], i));
    if (pQ.size() > k) {
      pQ.poll();
    }
  }

  int min = e[pQ.peek().index];
  int sum = 0;
  while (k-- > 0) {
    Pair p = pQ.poll();
    min = Math.min(e[p.index], min);
    sum += p.speed;
  }
  return (sum * min) % MOD;
}

class Pair {
  int speed, index;
  public Pair(int _s, int _i) {
    speed = _s; index = _i;
  }
}

题意:当两种方案的 efficiency 相等时,speed 之和更大的方案显然更优。问题转化成了如何快速求出每种 efficiency 的最优方案。

算法

  • 每个人按照效率 e 进行降序排列。
  • 在数组种选取 k 个最大的 speed。
public int maxPerformance(int n, int[] speed, int[] efficiency, int k) {
  int[][] pair = new int[n][2];
  for (int i = 0; i < n; i++) {
      pair[i][0] = speed[i];
      pair[i][1] = efficiency[i];
  }
  Arrays.sort(pair, (e1, e2) -> e2[1] - e1[1]);
  
  PriorityQueue<Integer> pQ = new PriorityQueue<>();
  long max = 0, sd = 0;
  for (int i = 0; i < n; i++) {
      pQ.add(pair[i][0]);
      sd += pair[i][0];
      if (pQ.size() > k) {
          sd -= pQ.poll();
      }
      max = Math.max(max, sd * pair[i][1]);
  }
  return (int)(max % ((int)1e9 + 7));
}

复杂度分析

  • 时间复杂度: O ( n l o g n ) O(n log n)
  • 空间复杂度: O ( k ) O(k)

发布了495 篇原创文章 · 获赞 105 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_43539599/article/details/104875916
今日推荐