Week 200 Weekly Tournament Problem Solution
The first question: Count the triples
Give you an integer array arr, and three integers a, b, and c. Please count the number of good triples.
If the triple (arr[i], arr[j], arr[k]) satisfies all the following conditions, it is considered a good triple.
-
0 <= i < j < k < arr.length
-
|arr[i] - arr[j]| <= a
-
|arr[j] - arr[k]| <= b
-
|arr[i] - arr[k]| <= c
-
Where |x| represents the absolute value of x.
Returns the number of good triples.
Example
输入:arr = [3,0,1,1,9,7], a = 7, b = 2, c = 3
输出:4
解释:一共有 4 个好三元组:[(3,0,1), (3,0,1), (3,1,1), (0,1,1)] 。
输入:arr = [1,1,2,2,3], a = 0, b = 0, c = 1
输出:0
解释:不存在满足所有条件的三元组。
Problem-solving ideas and code implementation:
Direct violence
class Solution {
public int countGoodTriplets(int[] arr, int a, int b, int c) {
int ans = 0;
for (int i = 0; i < arr.length - 2; i++) {
for (int j = i + 1; j < arr.length - 1; j++) {
for (int k = j + 1; k < arr.length; k++) {
if (Math.abs(arr[i] - arr[j]) <= a && Math.abs(arr[j] - arr[k]) <= b && Math.abs(arr[i] - arr[k]) <= c) {
ans++;
}
}
}
}
return ans;
}
}
Question 2: Find the winner of the array game
Give you an integer array arr composed of different integers and an integer k.
Each round of the game is played between the first two elements of the array (ie arr[0] and arr[1]). Comparing the size of arr[0] and arr[1], the larger integer will win the round and keep it at position 0, and the smaller integer will be moved to the end of the array. When an integer wins k consecutive rounds, the game ends, and the integer is the winner of the game.
Returns the integer that won the game.
The title data guarantees that there is a winner in the game.
Example
Input: arr = [2,1,3,5,4,6,7], k = 2
Output: 5
Explanation: Let’s take a look at each round of this game:
So there will be 4 rounds of the game, of which 5 is the winner, because it won 2 rounds in a row.
Problem-solving ideas and code implementation
The first idea of this question is to simulate the entire movement process, recording the current winner and the number of winning streaks each time, but after careful observation, it does not need to be so complicated. To put it another way, the meaning of this question is to fight the ring, after the winning streak reaches k times You can win and return to the master. The title requires the ringmaster to always be in the 1st ring. We changed our minds to let the ringmaster challenge each ring one by one, starting from the 1st, sweeping all subsequent rings and counting their winning streaks.
class Solution {
public int getWinner(int[] arr, int k) {
// 1号擂主
int ans = arr[0];
int count = 0;
for (int i = 1; i < arr.length; i++) {
// 擂主易主,注意易主的时候擂主已经获得1胜,别设置为0了
if (arr[i] > ans) {
count = 1;
ans = arr[i];
} else {
// 连胜则统计次数
count++;
}
// 判断当前连胜次数是否已经达标
if (count >= k) {
break;
}
}
return ans;
}
}
The third question: Arrange the minimum number of exchanges of the binary grid
Give you a binary grid of nxn. In each operation, you can select two adjacent rows of the grid to exchange.
A grid that meets the requirements needs to satisfy that the grids above the main diagonal are all 0.
Please return the minimum number of operations required to make the grid meet the requirements. If you cannot make the grid meet the requirements, please return -1.
The main diagonal refers to these grids from (1, 1) to (n, n).
Example
Problem-solving ideas and code implementation
This question directly sees the relationship between the number of consecutive 0s at the end of each row and the current row number. For example, the matrix is 3X3, and I am in the first row, then the first row needs to end 3-1 = 2 0s, and the second Row 3-2 = 1 0, and the third row 3-3 = 0 is not needed. Then we only need to determine the number of consecutive 0s at the end of each line, and then determine how many lines need to be changed and counted in the count accordingly. If it does not meet the requirements, return -1 as required by the title. See the code for details
class Solution {
public int minSwaps(int[][] grid) {
int ans = 0;
int[] arr = new int[grid.length];
for (int i = 0; i < grid.length; i++) {
arr[i] = getSeriousZeros(grid[i]);
}
// 此时判断arr[i]与len-1-i的关系即可
for (int i = 0; i < arr.length; i++) {
boolean flag = false;
for (int j = i;j < arr.length; j++) {
if (arr[j] >= arr.length - i - 1 && !flag) {
ans += swapCount(arr,i,j);
flag = true;
}
}
if (!flag) {
return -1;
}
}
return ans;
}
private static int swapCount(int[] arr,int i,int j) {
int ans = 0;
while (i < j) {
int tmp = arr[j - 1];
arr[j - 1] = arr[j];
arr[j] = tmp;
ans++;
j--;
}
return ans;
}
private static int getSeriousZeros(int[] arr){
int ans = 0;
int len = arr.length;
for (int i = len - 1; i >= 0; i--) {
if (arr[i] == 0) {
ans++;
} else {
break;
}
}
return ans;
}
}
Fourth question: Maximum score
You have two ordered arrays nums1 and nums2 with different elements.
A legal path is defined as follows:
-
Select the array nums1 or nums2 to start traversal (starting from the subscript 0).
-
Traverse the current array from left to right.
-
If you encounter a value that exists in both nums1 and nums2, then you can switch the path to the corresponding number in another array to continue traversing (but repeated numbers in a legal path will only be counted once).
-
The score is defined as the sum of different numbers in the legal path.
Please return the maximum score of all possible legal paths.
Since the answer may be very large, please take the remainder of 10^9 + 7 and return.
Example
Problem-solving ideas and code implementation
The finale of this week’s game, just simulate it directly, there are not too many obstacles in thinking, just pay attention to writing
class Solution {
public int maxSum(int[] nums1, int[] nums2) {
int MOD = 1000000007;
long ans1 = 0,ans2 = 0;
int len1 = nums1.length,len2 = nums2.length;
int i = 0,j = 0;
// 从两个数组开始的和
while (i < len1 && j < len2) {
if (nums1[i] < nums2[j]) {
ans1 += nums1[i];
i++;
} else if (nums1[i] > nums2[j]) {
ans2 += nums2[j];
j++;
} else {
ans1 = Math.max(ans1,ans2) + nums1[i];
ans2 = ans1;
i++;
j++;
}
}
// 剩下的加起来
while (i < len1) {
ans1 += nums1[i];
i++;
}
while (j < len2) {
ans2 += nums2[j];
j++;
}
return (int) (Math.max(ans1,ans2) % MOD);
}
}