class Solution {
public:
long long countOperationsToEmptyArray(vector<int>& nums) {
}
};
2659. 将数组清空
给你一个包含若干 互不相同 整数的数组 nums
,你需要执行以下操作 直到数组为空 :
请你返回需要多少个操作使 nums
为空。
示例 1:
输入:nums = [3,4,-1] 输出:5
Operation | Array |
---|---|
1 | [4, -1, 3] |
2 | [-1, 3, 4] |
3 | [3, 4] |
4 | [4] |
5 | [] |
示例 2:
输入:nums = [1,2,4,3] 输出:5
Operation | Array |
---|---|
1 | [2, 4, 3] |
2 | [4, 3] |
3 | [3, 4] |
4 | [4] |
5 | [] |
示例 3:
输入:nums = [1,2,3] 输出:3
Operation | Array |
---|---|
1 | [2, 3] |
2 | [3] |
3 | [] |
提示:
1 <= nums.length <= 105
-109 <= nums[i] <= 109
nums
中的元素 互不相同 。原站题解
golang 解法, 执行用时: 172 ms, 内存消耗: 8.9 MB, 提交时间: 2023-05-05 17:10:22
func countOperationsToEmptyArray(nums []int) int64 { n := len(nums) id := make([]int, n) for i := range id { id[i] = i } sort.Slice(id, func(i, j int) bool { return nums[id[i]] < nums[id[j]] }) ans := n for k := 1; k < n; k++ { if id[k] < id[k-1] { // 必须多走一整圈 ans += n - k // 减去前面删除的元素个数 } } return int64(ans) }
java 解法, 执行用时: 47 ms, 内存消耗: 54.5 MB, 提交时间: 2023-05-05 17:10:10
class Solution { public long countOperationsToEmptyArray(int[] nums) { int n = nums.length; var id = new Integer[n]; for (int i = 0; i < n; ++i) id[i] = i; Arrays.sort(id, (i, j) -> nums[i] - nums[j]); long ans = n; // 先把 n 计入答案 for (int k = 1; k < n; ++k) if (id[k] < id[k - 1]) // 必须多走一整圈 ans += n - k; // 减去前面删除的元素个数 return ans; } }
python3 解法, 执行用时: 172 ms, 内存消耗: 28.2 MB, 提交时间: 2023-05-05 17:09:56
class Solution: def countOperationsToEmptyArray(self, nums: List[int]) -> int: ans = n = len(nums) id = sorted(range(n), key=lambda x: nums[x]) for k, (pre, i) in enumerate(pairwise(id), 1): if i < pre: # 必须多走一整圈 ans += n - k # 减去前面删除的元素个数 return ans
golang 解法, 执行用时: 148 ms, 内存消耗: 9 MB, 提交时间: 2023-05-05 17:09:34
// 树状数组模板 type BIT []int // 将下标 i 上的数加一 func (t BIT) inc(i int) { for ; i < len(t); i += i & -i { t[i]++ } } // 返回闭区间 [1, i] 的元素和 func (t BIT) sum(i int) (res int) { for ; i > 0; i &= i - 1 { res += t[i] } return } // 返回闭区间 [left, right] 的元素和 func (t BIT) query(left, right int) int { return t.sum(right) - t.sum(left-1) } func countOperationsToEmptyArray(nums []int) int64 { n := len(nums) id := make([]int, n) for i := range id { id[i] = i } sort.Slice(id, func(i, j int) bool { return nums[id[i]] < nums[id[j]] }) ans := n // 先把 n 计入答案 t := make(BIT, n+1) // 下标从 1 开始 pre := 1 // 上一个最小值的位置,初始为 1 for k, i := range id { i++ // 下标从 1 开始 if i >= pre { // 从 pre 移动到 i,跳过已经删除的数 ans += i - pre - t.query(pre, i) } else { // 从 pre 移动到 n,再从 1 移动到 i,跳过已经删除的数 ans += n - pre + i - k + t.query(i, pre-1) } t.inc(i) // 删除 i pre = i } return int64(ans) }
java 解法, 执行用时: 69 ms, 内存消耗: 53.9 MB, 提交时间: 2023-05-05 17:09:18
class Solution { public long countOperationsToEmptyArray(int[] nums) { int n = nums.length; var id = new Integer[n]; for (int i = 0; i < n; ++i) id[i] = i; Arrays.sort(id, (i, j) -> nums[i] - nums[j]); long ans = n; // 先把 n 计入答案 var t = new BIT(n + 1); // 下标从 1 开始 int pre = 1; // 上一个最小值的位置,初始为 1 for (int k = 0; k < n; ++k) { int i = id[k] + 1; // 下标从 1 开始 if (i >= pre) // 从 pre 移动到 i,跳过已经删除的数 ans += i - pre - t.query(pre, i); else // 从 pre 移动到 n,再从 1 移动到 i,跳过已经删除的数 ans += n - pre + i - k + t.query(i, pre - 1); t.inc(i); // 删除 i pre = i; } return ans; } } // 树状数组模板 class BIT { private final int[] tree; public BIT(int n) { tree = new int[n]; } // 将下标 i 上的数加一 public void inc(int i) { while (i < tree.length) { ++tree[i]; i += i & -i; } } // 返回闭区间 [1, i] 的元素和 public int sum(int x) { int res = 0; while (x > 0) { res += tree[x]; x &= x - 1; } return res; } // 返回闭区间 [left, right] 的元素和 public int query(int left, int right) { return sum(right) - sum(left - 1); } }
python3 解法, 执行用时: 1956 ms, 内存消耗: 29 MB, 提交时间: 2023-05-05 17:09:04
class Solution: def countOperationsToEmptyArray(self, nums: List[int]) -> int: ans = n = len(nums) # 先把 n 计入答案 t = BIT(n + 1) # 下标从 1 开始 pre = 1 # 上一个最小值的位置,初始为 1 for k, i in enumerate(sorted(range(n), key=lambda i: nums[i])): i += 1 # 下标从 1 开始 if i >= pre: # 从 pre 移动到 i,跳过已经删除的数 ans += i - pre - t.query(pre, i) else: # 从 pre 移动到 n,再从 1 移动到 i,跳过已经删除的数 ans += i - pre + n - k + t.query(i, pre - 1) t.inc(i) # 删除 i pre = i return ans # 树状数组模板 class BIT: def __init__(self, n): self.tree = [0] * n # 将下标 i 上的数加一 def inc(self, i: int) -> None: while i < len(self.tree): self.tree[i] += 1 i += i & -i # 返回闭区间 [1, i] 的元素和 def sum(self, i: int) -> int: res = 0 while i > 0: res += self.tree[i] i &= i - 1 return res # 返回闭区间 [left, right] 的元素和 def query(self, left: int, right: int) -> int: return self.sum(right) - self.sum(left - 1)