LeetCode 分割整数数组,分割为两部分的和相等
2018-03-22 23:14
579 查看
/*! * @file 数组分割.cpp * @Date: 2018/03/22 15:03 * @author: sicaolong * @Contact: sicaolong@163.com * @brief: 将数组分割成两部分,两部分的和相等的部分;判断是否存在这样的分割 思路1:递归:1、先求出这个数组的和, 2、看这个和能不能被2整除,可以的话再进行下一步返回一个尝试分割的函数;trypartition(numbers,index,sum/2); 3、用numbers数组的[0....index]个数字来填充 sum的背包; 可以填充则返回true 4、tryPartition(numbers,index,sum)=tryPartition(numbers,index-1,sum)||tryPartition(numbers,index-1,sum-numbers[index]) 思路二:动态规划: 1、同上并判断和能否被2整除; 2、并且将背包容量C=sum/2; 3、初始状态:demo[j];只考虑第一个元素number[0]看看能不能填充; 4、状态转移;for(int i=0;i<n;++i) for(int j=C;j>=number[i];j--) memo[j]=memo[j]||memo[j-number[i]] * @TODO: */ #include<iostream> #include <vector> #include <assert.h> using namespace std; bool CanPartition(vector<int >&numbers); bool tryPartition(vector<int>&numbers, int index, int sum);//使用numbers[0........index]来填充一个容量为sum的背包; bool CanPartition_DP(vector<int >&numbers); vector<vector<int>>memo; //memo[i][c]表示使用索引[0...i]的这些元素,是否可以完全填充一个容量为C的背包,-1表示没有被计算,0表示不可以填充,1表示可以填充; //=========main函数 int main() { vector<int>a = {1,5,5,11}; vector<int>b = { 1, 2, 3, 8 }; if (CanPartition(a)) cout << "存在" << endl; else cout << "不存在" << endl; if (CanPartition_DP(b)) cout << "存在" << endl; else cout << "不存在" << endl; cout<<endl; } bool CanPartition(vector<int >&numbers) { int n = numbers.size(); int sum = 0; for (int i = 0; i < n; i++) { assert(numbers[i]>0); sum += numbers[i]; } if (sum % 2 != 0) return false; memo = vector<vector<int>>(n, vector<int>(sum / 2+1,-1));//一定要多加入一列,如果不加1 会出现越界!!! return tryPartition(numbers, n - 1, sum / 2); } bool tryPartition(vector<int>&numbers, int index, int sum)//[0....index]个的number数组的数字来填充sum背包 { if (sum == 0) return true; if (sum < 0 || index < 0) return false; //用从0-index-1的numbers数字能不能填充这个sum的背包,能填充,所以0-index也能填充 只不过不使用,如果不能填充,加上index能不能填充; //return tryPartition(numbers, index - 1, sum) || tryPartition(numbers, index - 1, sum - numbers[index]);//47行为递归用法,肯定包含重复的; if (memo[index][sum] != -1) return memo[index][sum]==1;//这里如果等于0,返回的是false,等于1返回true memo[index][sum] = ( tryPartition(numbers, index - 1, sum) || tryPartition(numbers, index-1, sum - numbers[index]) )? 1:0; return memo[index][sum]; } bool CanPartition_DP(vector<int >&numbers) { int sum = 0; int n = numbers.size(); for (int i = 0; i < n;i++) { assert(numbers[i]>0); sum += numbers[i]; } if (sum % 2) return false;//判断能不能被2整除 int C = sum >> 1;//背包容量 vector<bool>memo(C + 1, false); for (int j = 0; j <= C; j++)//容量从0-C,只考虑第一个number,看看能不能填满, memo[j] = (numbers[0] == j); for (int i = 1; i < n;i++)//从第一个开始,放,直到最后一个 for (int j = C; j >= numbers[i]; j--) memo[j] = memo[j-1] || memo[j - numbers[i]]; return memo[C]; }
相关文章推荐
- 数组分割, 把数组分解成和相等的两部分--动态规划方法
- 数组分割,把数组分割成和相等的两部分--递归方法
- 一个正数数组分成相等的四部分分割值不算(O(n))方法
- 将整数数组进行m等分,使得每一个部分的和相等且m最大
- leetcode 27. Remove Element(C语言,快速排序思想,剔除数组中与目标值相等的数)20
- leetcode 27 Remove Element(移除数组中的与val相等的元素)
- 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变。
- 一个整数数组,长度为n,将其分为m 份,使各份的和相等,求m 的最大值
- Leetcode - Hash Table - 349+350 Intersection of Two Arrays(快速返回两数组重叠部分)
- 【微软谷歌面试100题--【45】一个整数数组,长度为n,将其分为m 份,使各份的和相等,求m 的最大值
- 写一个函数,随机地从大小为n的数组中选取m个整数。要求每个元素被选中的概率相等。
- leetcode 1 Two Sum(在无序数组中找两个数之和与目标值相等,两种方法)
- 面试题系列-整数数组长度为n,分为m份使各份的和相等,求最大的m
- 仅用O(1)的空间,将整数数组按奇偶数分成2部分,数组左边是奇数、右边是偶数
- 输入整数数组,调整顺序,使得奇数位于前半部分,偶数位于后半部分
- 算法习题45:对于一个整数矩阵,存在一种运算,对矩阵中任意元素加一时,需要其相邻(上下左右)某一个元素也加一;;;一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- leetcode 525. Contiguous Array 统计1和0相等最长子数组 + map统计index
- 一个整数数组,长度为n,将其分为m份,使各份的和相等,求m的最大值
- LeetCode 548. Split Array with Equal Sum (分割数组使得子数组的和都相同)$
- 调整数组使奇数全部都位于偶数前面。 题目: 输入一个整数数组,实现一个函数,来调整该数组中数字的顺序使得数组中所有的奇数位于数组的前半部分,所有偶数位于数组的后半部分。