package LeetCode_1395
/**
* 1395. Count Number of Teams
* https://leetcode.com/problems/count-number-of-teams/
* There are n soldiers standing in a line. Each soldier is assigned a unique rating value.
You have to form a team of 3 soldiers amongst them under the following rules:
Choose 3 soldiers with index (i, j, k) with rating (rating[i], rating[j], rating[k]).
A team is valid if: (rating[i] < rating[j] < rating[k]) or (rating[i] > rating[j] > rating[k]) where (0 <= i < j < k < n).
Return the number of teams you can form given the conditions. (soldiers can be part of multiple teams).
Example 1:
Input: rating = [2,5,3,4,1]
Output: 3
Explanation: We can form three teams given the conditions. (2,3,4), (5,4,1), (5,3,1).
Example 2:
Input: rating = [2,1,3]
Output: 0
Explanation: We can't form any team given the conditions.
Example 3:
Input: rating = [1,2,3,4]
Output: 4
Constraints:
1. n == rating.length
2. 3 <= n <= 1000
3. 1 <= rating[i] <= 10^5
4. All the integers in rating are unique.
* */
class Solution {
/*
* solution 1: bruce force, Time:O(n^3), Space:O(1)
* solution 2: dp, Time:O(n^2), Space:O(1)
* */
fun numTeams(rating: IntArray): Int {
var result = 0
val n = rating.size
val dp = IntArray(n)
for (i in 1 until n) {
var increasingCount = 0
for (j in 0 until i) {
if (rating[j] < rating[i]) {
increasingCount++
/*
* like j in the middle, if (rating[j]<rating[i]), find out one result matching:
* rating[j-1]<rating[j]<rating[i],
* dp[j]: meaning there are how many number less than rating[j], from index_0 to index_j,
* */
result += dp[j]
}
//dp[i]: there are how many number less than rating[i], from index_0 to index_i,
dp[i] = increasingCount
}
}
//reset dp arra and reverse rating to do again, just like decreasing
for (i in 0 until n) {
dp[i] = 0
}
rating.reverse()
for (i in 1 until n) {
var increasingCount = 0
for (j in 0 until i) {
if (rating[j] < rating[i]) {
increasingCount++
result += dp[j]
}
dp[i] = increasingCount
}
}
return result
}
}