Welcome to Subscribe On Youtube
3886. Sum of Sortable Integers
Description
You are given an integer array nums of length n.
An integer k is called sortable if k divides n and you can sort nums in non-decreasing order by sequentially performing the following operations:
- Partition
numsinto consecutive subarrays of lengthk. - Cyclically rotate each subarray independently any number of times to the left or to the right.
Return an integer denoting the sum of all possible sortable integers k.
Example 1:
Input: nums = [3,1,2]
Output: 3
Explanation:
- For
n = 3, possible divisors are 1 and 3. - For
k = 1: each subarray has one element. No rotation can sort the array. - For
k = 3: the single subarray[3, 1, 2]can be rotated once to produce[1, 2, 3], which is sorted. - Only
k = 3is sortable. Hence, the answer is 3.
Example 2:
Input: nums = [7,6,5]
Output: 0
Explanation:
- For
n = 3, possible divisors are 1 and 3. - For
k = 1: each subarray has one element. No rotation can sort the array. - For
k = 3: the single subarray[7, 6, 5]cannot be rotated into non-decreasing order. - No
kis sortable. Hence, the answer is 0.
Example 3:
Input: nums = [5,8]
Output: 3
Explanation:
- For
n = 2, possible divisors are 1 and 2. - Since
[5, 8]is already sorted, every divisor is sortable. Hence, the answer is1 + 2 = 3.
Constraints:
1 <= n == nums.length <= 1051 <= nums[i] <= 105
Solutions
Solution 1
-
class Solution { public int sortableIntegers(int[] nums) { int n = nums.length; int[] prefMax = new int[n + 1]; for (int i = 0; i < n; ++i) { prefMax[i + 1] = Math.max(prefMax[i], nums[i]); } int[] suffMin = new int[n + 1]; suffMin[n] = 1000000000; for (int i = n - 1; i >= 0; --i) { suffMin[i] = Math.min(nums[i], suffMin[i + 1]); } int[] prefDrop = new int[n]; for (int i = 1; i < n; ++i) { prefDrop[i] = prefDrop[i - 1] + (nums[i - 1] > nums[i] ? 1 : 0); } int ans = 0; for (int i = 1; i <= n / i; ++i) { if (n % i == 0) { if (check(nums, prefMax, suffMin, prefDrop, i)) { ans += i; } if (i != n / i && check(nums, prefMax, suffMin, prefDrop, n / i)) { ans += n / i; } } } return ans; } private boolean check(int[] nums, int[] prefMax, int[] suffMin, int[] prefDrop, int k) { int n = nums.length; for (int start = 0; start < n; start += k) { int end = start + k - 1; int drops = prefDrop[end] - prefDrop[start]; if (nums[end] > nums[start]) { ++drops; } if (drops > 1 || prefMax[start] > suffMin[start]) { return false; } } return true; } } -
class Solution { public: int sortableIntegers(vector<int>& nums) { int n = nums.size(); vector<int> prefMax(n + 1); for (int i = 0; i < n; ++i) { prefMax[i + 1] = max(prefMax[i], nums[i]); } vector<int> suffMin(n + 1, 1000000000); for (int i = n - 1; i >= 0; --i) { suffMin[i] = min(nums[i], suffMin[i + 1]); } vector<int> prefDrop(n); for (int i = 1; i < n; ++i) { prefDrop[i] = prefDrop[i - 1] + (nums[i - 1] > nums[i]); } auto check = [&](int k) { for (int start = 0; start < n; start += k) { int end = start + k - 1; int drops = prefDrop[end] - prefDrop[start]; if (nums[end] > nums[start]) { ++drops; } if (drops > 1 || prefMax[start] > suffMin[start]) { return false; } } return true; }; int ans = 0; for (int i = 1; i <= n / i; ++i) { if (n % i == 0) { if (check(i)) { ans += i; } if (i != n / i && check(n / i)) { ans += n / i; } } } return ans; } }; -
class Solution: def sortableIntegers(self, nums: list[int]) -> int: n = len(nums) pref_max = [0] * (n + 1) for i, x in enumerate(nums): pref_max[i + 1] = max(pref_max[i], x) suff_min = [10**9] * (n + 1) for i in range(n - 1, -1, -1): suff_min[i] = min(nums[i], suff_min[i + 1]) pref_drop = [0] * n for i in range(1, n): pref_drop[i] = pref_drop[i - 1] + (nums[i - 1] > nums[i]) def check(k: int) -> bool: for start in range(0, n, k): end = start + k - 1 drops = pref_drop[end] - pref_drop[start] if nums[end] > nums[start]: drops += 1 if drops > 1 or pref_max[start] > suff_min[start]: return False return True ans = 0 i = 1 while i <= n // i: if n % i == 0: if check(i): ans += i other = n // i if i != other and check(other): ans += other i += 1 return ans -
func sortableIntegers(nums []int) int { n := len(nums) prefMax := make([]int, n+1) for i, x := range nums { prefMax[i+1] = max(prefMax[i], x) } suffMin := make([]int, n+1) suffMin[n] = 1000000000 for i := n - 1; i >= 0; i-- { suffMin[i] = min(nums[i], suffMin[i+1]) } prefDrop := make([]int, n) for i := 1; i < n; i++ { prefDrop[i] = prefDrop[i-1] if nums[i-1] > nums[i] { prefDrop[i]++ } } check := func(k int) bool { for start := 0; start < n; start += k { end := start + k - 1 drops := prefDrop[end] - prefDrop[start] if nums[end] > nums[start] { drops++ } if drops > 1 || prefMax[start] > suffMin[start] { return false } } return true } ans := 0 for i := 1; i <= n/i; i++ { if n%i == 0 { if check(i) { ans += i } if i != n/i && check(n/i) { ans += n / i } } } return ans } -
function sortableIntegers(nums: number[]): number { const n = nums.length; const prefMax = new Array<number>(n + 1).fill(0); for (let i = 0; i < n; i++) { prefMax[i + 1] = Math.max(prefMax[i], nums[i]); } const suffMin = new Array<number>(n + 1).fill(1e9); for (let i = n - 1; i >= 0; i--) { suffMin[i] = Math.min(nums[i], suffMin[i + 1]); } const prefDrop = new Array<number>(n).fill(0); for (let i = 1; i < n; i++) { prefDrop[i] = prefDrop[i - 1] + (nums[i - 1] > nums[i] ? 1 : 0); } const check = (k: number): boolean => { for (let start = 0; start < n; start += k) { const end = start + k - 1; let drops = prefDrop[end] - prefDrop[start]; if (nums[end] > nums[start]) { drops++; } if (drops > 1 || prefMax[start] > suffMin[start]) { return false; } } return true; }; let ans = 0; for (let i = 1; i <= Math.floor(n / i); i++) { if (n % i === 0) { const other = n / i; if (check(i)) { ans += i; } if (i !== other && check(other)) { ans += other; } } } return ans; }