1770. Max Score from Multiplication Operations

1770. Max Score from Multiplication Operations

Question

You are given two integer arrays nums and multipliers** **of size n and m respectively, where n >= m. The arrays are 1-indexed.

You begin with a score of 0. You want to perform exactly m operations. On the i<sup>th</sup> operation (1-indexed), you will:

  • Choose one integer x from **either the start or the end **of the array nums.
  • Add multipliers[i] * x to your score.
  • Remove x from the array nums.

Return *the maximum score after performing *m operations.

Solution

动态规划,dp[][]数组记录左边取的个数和右边取的个数。

从取1开始到取multipliers的长度位置开始遍历。
然后从left取0个开始,直到left取i个为止遍历。
计算对应的right指针位置。

注意访问数组时需要访问left和right的上一个位置。

如果left为0,则只能取右侧的上一个位置加上右侧的上一个数值乘以mul。
如果right为0,则只能取左侧的上一个位置加上左侧的上一个数值乘以mul。
否则取两者之间的最大值。

最后遍历数组中left + right和为m的位置,并返回最大值。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
class Solution {
public int maximumScore(int[] nums, int[] multipliers) {
int n = nums.length, m = multipliers.length;
int[][] dp = new int[m+1][m+1];

for(int i = 1; i <= m; i++){
int mul = multipliers[i-1];
for(int l = 0; l <= i; l++){
int r = i - l;
int iL = l - 1, iR = n - r;
if(l == 0) dp[l][r] = dp[l][r-1] + mul * nums[iR];
else if(r == 0) dp[l][r] = dp[l-1][r] + mul * nums[iL];
else dp[l][r] = Math.max(dp[l-1][r] + mul * nums[iL], dp[l][r-1] + mul * nums[iR]);
}
}
int ans = Integer.MIN_VALUE;
for(int l = 1; l <= m; l++){
int r = m - l;
ans = Math.max(ans, dp[l][r]);
}
return ans;
}
}
1457. Pseudo-Palindromic Paths in a Binary Tree

1457. Pseudo-Palindromic Paths in a Binary Tree

Question

Given a binary tree where node values are digits from 1 to 9. A path in the binary tree is said to be pseudo-palindromic if at least one permutation of the node values in the path is a palindrome.

Return the number of pseudo-palindromic paths going from the root node to leaf nodes.

Solution

用数组bin[]记录一个树枝上的节点。

回溯,遇到根节点则判断数组bin[]中是否只有0个或1个奇数的数字。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/**
* Definition for a binary tree node.
* public class TreeNode {
* int val;
* TreeNode left;
* TreeNode right;
* TreeNode() {}
* TreeNode(int val) { this.val = val; }
* TreeNode(int val, TreeNode left, TreeNode right) {
* this.val = val;
* this.left = left;
* this.right = right;
* }
* }
*/
class Solution {
int res;
int[] bin;
public int pseudoPalindromicPaths (TreeNode root) {
res = 0;
bin = new int[10];
backtrack(root);
return res;
}

private void backtrack(TreeNode root){
if(root.left == null && root.right == null){
bin[root.val]++;
boolean flag = false;
for(int i = 0; i < bin.length; i++){
if(flag && (bin[i] & 1) == 1){
bin[root.val]--;
return;
}
else if((bin[i] & 1) == 1) flag = true;
}
res++;
bin[root.val]--;
return;
}
bin[root.val]++;
if(root.left != null) backtrack(root.left);
if(root.right != null) backtrack(root.right);
bin[root.val]--;
}
}
393. UTF-8 Validation

393. UTF-8 Validation

Question

Given an integer array data representing the data, return whether it is a valid UTF-8 encoding (i.e. it translates to a sequence of valid UTF-8 encoded characters).

A character in UTF8 can be from 1 to 4 bytes long, subjected to the following rules:

  1. For a 1-byte character, the first bit is a 0, followed by its Unicode code.
  2. For an n-bytes character, the first n bits are all one’s, the n + 1 bit is 0, followed by n - 1 bytes with the most significant 2 bits being 10.

x denotes a bit in the binary form of a byte that may be either 0 or 1.

**Note: **The input is an array of integers. Only the least significant 8 bits of each integer is used to store the data. This means each integer represents only 1 byte of data.

Solution

位运算,循环更新UTF头部的位置start。
getByte()方法用来计算位数。
check()方法用来检查从start+1开始直到位数结束是否二进制位数以10开头。
isStartWith10()方法使用掩码判断二进制是否以10开头。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
int[] dt;
final int MASK = 0b11000000;
public boolean validUtf8(int[] data) {
dt = data;
int start = 0;

while(start < data.length){
int bit = getByte(start);
if(bit == -1 || start + bit > data.length) return false;
if(!check(start, bit)) return false;
start += bit;
}
return true;
}

private int getByte(int start){
int bit = 5;
for(int i = 0; i < 8; i++){
if((dt[start] & 1) == 0) bit = 7 - i;
dt[start] >>= 1;
}
if(bit == 0) return 1;
else if(bit == 1 || bit > 4) return -1;
else return bit;
}

private boolean check(int start, int bit){
for(int i = start + 1; i < start + bit; i++) if(!isStartWith10(dt[i])) return false;
return true;
}

private boolean isStartWith10(int num){
return (num & MASK) == 0b10000000;
}
}
1383. Maximum Performance of a Team

1383. Maximum Performance of a Team

Question

You are given two integers n and k and two integer arrays speed and efficiency both of length n. There are n engineers numbered from 1 to n. speed[i] and efficiency[i] represent the speed and efficiency of the i<sup>th</sup> engineer respectively.

Choose at most k different engineers out of the n engineers to form a team with the maximum performance.

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

Return the maximum performance of this team. Since the answer can be a huge number, return it modulo 10<sup>9</sup><span> </span>+ 7.

Solution

排序,将所有工程师根据其效率降序排列。

此时遍历时后一个工程师的效率一定小于等于前一个工程师。

因此,此时遍历到每一个工程师,其前面所有的工程师的efficiency均大于等于其本身。
维护一个所有选取工程师的总速度ttSpd,每次计算并更新max的值。
用最小堆来维护选取的工程师速度,如果优先级队列的尺寸超过k-1,则poll掉队列内最低的速度。

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Solution {
public int maxPerformance(int n, int[] speed, int[] efficiency, int k) {
final int mod = (int) Math.pow(10, 9) + 7;
int[][] engineer = new int[n][2];

for(int i = 0; i < n; i++){
engineer[i][0] = speed[i];
engineer[i][1] = efficiency[i];
}

Arrays.sort(engineer, new Comparator<int[]>(){
public int compare(int[] a, int[] b){
return b[1] - a[1];
}
});

long max = 0, ttSpd = 0;

PriorityQueue<Integer> pq = new PriorityQueue<>();
for(int i = 0; i < n; i++){
int s = engineer[i][0], e = engineer[i][1];
ttSpd += s;
max = Math.max(max, ttSpd * e);
pq.add(s);
if(pq.size() == k) ttSpd -= pq.poll();
}

return (int) (max % mod);
}
}

1996. The Number of Weak Characters in the Game

1996. The Number of Weak Characters in the Game

Question

You are playing a game that contains multiple characters, and each of the characters has two main properties: attack and defense. You are given a 2D integer array properties where properties[i] = [attack<sub>i</sub>, defense<sub>i</sub>] represents the properties of the i<sup>th</sup> character in the game.

A character is said to be weak if any other character has both attack and defense levels strictly greater than this character’s attack and defense levels. More formally, a character i is said to be weak if there exists another character j where attack<sub>j</sub><span> </span>> attack<sub>i</sub> and defense<sub>j</sub><span> </span>> defense<sub>i</sub>.

Return the number of weak characters.

Solution

本题与354. Russian Doll Envelopes相近。

首先对数组进行排序,根据角色的attack数值降序排序,如果两者的attack数值相等,则根据两者的defence升序排序。

记录一个遍历过的最大defence数值maxDefence,遍历数组,如果当前maxDef大于角色的防御值,则此时当前遍历角色的attack与defence均严格小于上一个计算的角色,因此count加一。
否则更新maxDef。

*由于attack是降序的,因此可以确定遍历时下一组数组的attack一定更弱。(由于相同attack的角色是根据defence升序排列,因此记录maxDef时会逐个更新maxDef的值。)

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Solution {
public int numberOfWeakCharacters(int[][] properties) {
int count = 0, maxDef = Integer.MIN_VALUE;

Arrays.sort(properties, new Comparator<int[]>(){
public int compare(int[] a, int[] b){
if(a[0] == b[0]) return a[1] - b[1];
return b[0] - a[0];
}
});

for(int[] character : properties){
if(maxDef > character[1]) count++;
else maxDef = character[1];
}
return count;
}
}