• 1755. Closest Subsequence Sum


    题目

    题意:从一个数组找出一个子集,使得子集的和给定的目标最相近。

    题解:数组的长度为40,找出全部子集一共有240种可能性,如果把一个数组平均分成两部分,分别算出两部分的所有子集和,每部分有220种可能,
    然后再二分查找答案。

    遇到这种在数组里找所有子集和,

    class Solution {
    public:
       map<int, int> m;
    int sum[1000005];
    int sum2[1000005];
    int p;
    void fun(int n, int i, int s,vector<int>& nums, int* sum)
    {
    	if (m[s] == 0)
    	{
    		m[s] = 1;
    		sum[p++] = s;
    	}
    	
    	for (int j = i + 1; j < n; j++)
    	{
    		fun(n, j, s+nums[j], nums, sum);
    	}
    }
        
        int minAbsDifference(vector<int>& nums, int goal)
    {
    	int ans = INT_MAX;
    	int n = nums.size()/2;
    	p = 0;
    	for (int i = 0; i < n; i++)
    	{
    		fun(n, i, nums[i], nums, sum);
    	}
    	int p1 = p;
    	m.clear();
    	for (int i = 0; i < p1; i++)
    	{
    		ans = min(ans, abs(sum[i] - goal));
    	}
    	p = 0;
    	for (int i = n; i < nums.size(); i++)
    	{
    		fun(nums.size(), i, nums[i],nums, sum2);
    	}
    	for (int i = 0; i < p; i++)
    	{
    		ans = min(ans, abs(sum2[i] - goal));
    	}
    
    	sort(sum, sum + p1);
    	
    	// 1 2 5 6
    	for (int i = 0; i < p; i++)
    	{
    		int x = sum2[i];
    
    		int l = 0;
    		int r = p1;
    
    		while (l <= r)
    		{
    			int mid = (l + r) / 2;
    			ans = min(ans, abs(sum[mid] + x - goal));
    			if (sum[mid] + x > goal)
    			{
    				r = mid - 1;
    			}
    			else if (sum[mid] + x < goal)
    			{
    				l = mid + 1;
    			}
    			else
    			{
    				return 0;
    			}
    		}
    	}
    	return ans;
    }
    
    
    };
    
  • 相关阅读:
    百度--买帽子
    网易--双核处理器
    京东--通过考试
    简单错误记录
    链表中的倒数第k个结点
    数值的整数次方
    二进制中1的个数
    TCP 三次握手
    旋转数组的最小数字
    用两个栈实现队列
  • 原文地址:https://www.cnblogs.com/dacc123/p/14400440.html
Copyright © 2020-2023  润新知