限制条件子集 --- lintcode 818

已知:

给定一个数组,给定一个target,求满足下面条件的所有子集个数:

条件:子集的最小值和最大值要小于给定的target。


示例:

给定nums = [1,5,2,4,3],给定target为5,返回为5.

五个子集如下: [1] [2] [1,2] [1,3] [1,2,3]


思路:

首先,子集不能为空:

如果子集只有一个数,那么计算下原数组中大小不到target一半的数,这是结果的第一个来源。

如果子集有两个及以上的数,假设最大数下标为x,最小数下标为y,则总共有2^(y - x -1)种可能性

(假设y和x之间有n个数字,每个数字为0或者1,总共就是2^n种可能性,且每一种都不一样


综上,代码如下:

public class Solution {
    public long subsetWithTarget(int[] nums, int target) {
        Arrays.sort(nums);
		long ret = 0;

		for (int num : nums) {
			if (2 * num < target) {
				ret++;
			}
		}

		loop: for (int i = 0; nums[i] < target; i++) {
			int j = nums.length - 1;
			while (nums[i] + nums[j] >= target) {
				j--;
			}

			if (j <= i) {
				break loop;
			}

			while (i < j) {
				ret += Math.pow(2, j - i - 1);
				j--;
			}
		}

		return ret;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值