原题网址:https://leetcode.com/problems/count-of-range-sum/
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:
Given nums = [-2, 5, -1]
, lower = -2
, upper = 2
,
Return 3
.
The three ranges are : [0, 0]
, [2, 2]
, [0, 2]
and their respective sums are: -2, -1, 2
.
方法一:使用TreeMap来保存每个前缀和的计数。
public class Solution {
public int countRangeSum(int[] nums, int lower, int upper) {
if (nums == null || nums.length==0) return 0;
long[] sums = new long[nums.length];
sums[0] = nums[0];
for(int i=1; i treemap = new TreeMap<>();
for(int i=0; i
public class Solution {
Node root;
private int sub(Node node, long lower, long upper) {
// System.out.printf("sub=%s, lower=%d, upper=%d\n", node==null?"null":Long.toString(node.val), lower, upper);
if (node == null) return 0;
if (node.val < lower) return sub(node.right, lower, upper);
if (upper < node.val) return sub(node.left, lower, upper);
return node.count + sub(node.left, lower, node.val-1) + sub(node.right, node.val+1, upper);
}
private void insert(Node node, long val) {
if (node.val < val) {
if (node.right == null) node.right = new Node(val);
insert(node.right, val);
} else if (val < node.val) {
if (node.left == null) node.left = new Node(val);
insert(node.left, val);
} else {
node.count ++;
}
}
public int countRangeSum(int[] nums, int lower, int upper) {
if (nums == null || nums.length == 0) return 0;
long[] sums = new long[nums.length];
sums[0] = nums[0];
for(int i=1; i
public class Solution {
private Node build(long[] nums, int from, int to) {
if (from>to) return null;
int m = (from+to)/2;
Node node = new Node(nums[m]);
if (from node.val) {
update(node.right, val);
} else {
node.count ++;
}
}
private int smaller(Node node, long val) {
if (node == null) return 0;
if (node.val <= val) {
return node.count + smaller(node.right, val);
} else {
return smaller(node.left, val);
}
}
public int countRangeSum(int[] nums, int lower, int upper) {
if (nums == null || nums.length == 0) return 0;
long[] sums = new long[nums.length];
sums[0] = nums[0];
for(int i=1; i set = new HashSet<>();
for(int i=0; i
public class Solution {
private Node root;
private Node build(long[] ranges, int min, int max) {
if (min>max) return null;
Node Node = new Node(ranges[min], ranges[max]);
if (min==max) return Node;
int m = (min+max)/2;
Node.left = build(ranges, min, m);
Node.right = build(ranges, m+1, max);
return Node;
}
private void update(Node node, long val) {
if (node == null) return;
if (val < node.min || node.max < val) return;
node.count ++;
update(node.left, val);
update(node.right, val);
}
private int query(Node node, long from, long to) {
if (node==null) return 0;
if (node.max < from || to < node.min) return 0;
if (from <= node.min && node.max <= to) return node.count;
return query(node.left, from, to) + query(node.right, from, to);
}
public int countRangeSum(int[] nums, int lower, int upper) {
if (nums == null || nums.length == 0) return 0;
long[] sums = new long[nums.length];
sums[0] = nums[0];
Set set = new HashSet<>();
set.add(sums[0]);
for(int i=1; i
public class Solution {
private int sort(long[] sums, int from, int to, int lower, int upper) {
if (from > to) return 0;
if (from == to) return (lower <= sums[from] && sums[from] <= upper) ? 1 : 0;
int count = 0;
int m = (from + to) / 2;
count = sort(sums, from, m, lower, upper) + sort(sums, m+1, to, lower, upper);
for(int i=from, j=m+1, k=m+1; i<=m; i++) {
while (j<=to && sums[j] - sums[i] < lower) j++;
while (k<=to && sums[k] - sums[i] <= upper) k++;
count += k - j;
}
long[] merged = new long[to-from+1];
int l=from, r=m+1;
for(int i=0, j=from, k=m+1; im) merged[i] = sums[k++];
else if (k>to) merged[i] = sums[j++];
else if (sums[j] <= sums[k]) merged[i] = sums[j++];
else merged[i] = sums[k++];
}
System.arraycopy(merged, 0, sums, from, merged.length);
return count;
}
public int countRangeSum(int[] nums, int lower, int upper) {
if (nums == null || nums.length == 0) return 0;
long[] sums = new long[nums.length];
sums[0] = nums[0];
for(int i=1; i
未实现,留待下次。
二叉树不一定要用指针实现,可以用数组实现。