Description:
Given an integer array nums, return the number of range sums that lie in [lower, upper] inclusive.
Range sum S(i, j) is defined as the sum of the elements in nums between indices i and j (i ≤ j), inclusive.
Note:
A naive algorithm of O(n2) is trivial. You MUST do better than that.
Example:
Input: nums = [-2,5,-1], lower = -2, upper = 2,
Output: 3
Explanation: The three ranges are : [0,0], [2,2], [0,2] and their respective sums are: -2, -1, 2.
Constraints:
0 <= nums.length <= 10^4
題目描述:
給定一個整數數組 nums,返回區間和在 [lower, upper] 之間的個數,包含 lower 和 upper。
區間和 S(i, j) 表示在 nums 中,位置從 i 到 j 的元素之和,包含 i 和 j (i ≤ j)。
說明:
最直觀的算法複雜度是 O(n2) ,請在此基礎上優化你的算法。
示例 :
輸入: nums = [-2,5,-1], lower = -2, upper = 2,
輸出: 3
解釋: 3個區間分別是: [0,0], [2,2], [0,2],它們表示的和分別爲: -2, -1, 2。
思路:
- 排序再交叉插入原數組
比如 [1, 2, 3], [4, 5], 插入之後就可以得到 [1, 4, 2, 5, 3]
時間複雜度O(nlgn), 空間複雜度O(1) - 利用快速排序的思想, 找到數組的中位數
然後將數組按中位數分開, 那麼中位數左邊都比中位數小, 右邊都比中位數大
然後將中位數兩邊的數組反向, 再依次插入就能得到擺動數組
比如 [1, 2, 5, 5, 5, 5, 6, 7] -> [5, 5, 2, 1], [7, 6, 5, 5] -> [5, 7, 5, 6, 2, 5, 1, 5]
時間複雜度O(nlgn), 空間複雜度O(1)
代碼:
C++:
#define a(i) nums[(((i) << 1) + 1) % (n | 1)]
class Solution
{
public:
void wiggleSort(vector<int>& nums)
{
nth_element(nums.begin(), nums.begin() + (nums.size() >> 1), nums.end());
int n = nums.size(), mid = nums[nums.size() >> 1], i = 0, j = 0, k = nums.size() - 1;
while (j <= k)
{
if (a(j) > mid)
{
swap(a(i), a(j));
++i;
++j;
}
else if (a(j) < mid)
{
swap(a(j), a(k));
--k;
}
else ++j;
}
}
};
Java:
class Solution {
private void swap(int[] nums, int p, int q) {
int temp = nums[p];
nums[p] = nums[q];
nums[q] = temp;
}
private int getIndex(int n, int i) {
return i <= (n - 1) / 2 ? i * 2 : (i - (n + 1) / 2) * 2 + 1;
}
private int getKth(int[] nums, int k) {
int n = nums.length, start = 0, end = n - 1;
while (true) {
int pivot = nums[getIndex(n, end)], p = start, q = p;
for (int i = start; i < end; i++)
if (nums[getIndex(n, i)] <= pivot) {
swap(nums, getIndex(n, q++), getIndex(n, i));
if (nums[getIndex(n, q - 1)] < pivot) swap(nums, getIndex(n, p++), getIndex(n, q - 1));
}
swap(nums, getIndex(n, q++), getIndex(n, end));
if (k < p - start) end = p - 1;
else if (k < q - start) return pivot;
else {
k -= q - start;
start = q;
}
}
}
public void wiggleSort(int[] nums) {
int n = nums.length, mid = (n - 1) / 2;
getKth(nums, mid);
for (int p = 0, q = mid; p < q; p++, q--) swap(nums, getIndex(n, p), getIndex(n, q));
for (int p = mid + 1, q = n - 1; p < q; p++, q--) swap(nums, getIndex(n, p), getIndex(n, q));
}
}
Python:
class Solution:
def wiggleSort(self, nums: List[int]) -> None:
"""
Do not return anything, modify nums in-place instead.
"""
nums[0::2], nums[1::2] = sorted(nums)[:len(nums) - (len(nums) >> 1)][::-1], sorted(nums)[len(nums) - (len(nums) >> 1):][::-1]