1498. 满足条件的子序列数目
题目:
思路:
【1】首先是明确约束
1)「子序列」是不要求连续的; 2)只关心这个子序列的最小值和最大值,而不关心元素的相对顺序;
代码展示:
//时间32 ms 击败 75.71% //内存53.1 MB 击败 79.10% class Solution { public int numSubseq(int[] nums, int target) { Arrays.sort(nums); int n = nums.length; int mod = 1000000007; int[] dp = new int[n]; dp[0] = 1; for (int i = 1; i < n; i++) { dp[i] = (dp[i - 1] << 1) % mod; } int res = 0; for (int left = 0, right = n - 1; left <= right; ) { if (nums[left] + nums[right] <= target) { res = (res + dp[right - left]) % mod; left++; } else { right--; } } return res; } } //时间92 ms 击败 5.65% //内存54 MB 击败 30.51% class Solution { static final int P = 1000000007; static final int MAX_N = 100005; int[] f = new int[MAX_N]; public int numSubseq(int[] nums, int target) { pretreatment(); Arrays.sort(nums); int ans = 0; for (int i = 0; i < nums.length && nums[i] * 2 <= target; ++i) { int maxValue = target - nums[i]; int pos = binarySearch(nums, maxValue) - 1; int contribute = (pos >= i) ? f[pos - i] : 0; ans = (ans + contribute) % P; } return ans; } public void pretreatment() { f[0] = 1; for (int i = 1; i < MAX_N; ++i) { f[i] = (f[i - 1] << 1) % P; } } public int binarySearch(int[] nums, int target) { int low = 0, high = nums.length; while (low < high) { int mid = (high - low) / 2 + low; if (mid == nums.length) { return mid; } int num = nums[mid]; if (num <= target) { low = mid + 1; } else { high = mid; } } return low; } }