元素互不相邻的最大和子数组
来源:互联网 发布:mac电磁阀型号 编辑:程序博客网 时间:2024/05/16 05:47
题目
对于一个给定的数组,在其中选取其子数组,要求相邻的元素不能选取,且要保证选出的子数组元素和最大。输入数组长度及其元素,输出所选子数组的和。
- 测试输入
7
4 2 6 1 3 5 8 - 测试输出
21
分析1
为了让子数组和最大,应该尽可能让它包含更多的元素,并且相邻元素不能选取,所以选取的任意两个数字之间最多间隔两个数,因为假设如果间隔了三个而子数组和最大,那么最中间的那个数一定可以选中,此时子数组和也一定比之前更大,产生矛盾。由此可见,本题只需要分析连续的三个元素的关系即可。
按照第
代码1
import java.util.Scanner;public class NotAdjacentLine { static int solution(int[] array, int n) { if (n < 1) return 0; if (n == 1) return array[0]; return Math.max(solution(array, n - 1), solution(array, n - 2) + array[n - 1]); } static int solution2(int[] array, int n) { int[] s = new int[n + 1]; s[0] = 0; s[1] = array[0]; for (int i = 2; i < n + 1; i++) { int takei = s[i - 2] + array[i - 1]; int skipi = s[i - 1]; s[i] = Math.max(takei, skipi); } return s[n]; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] array = new int[n]; for (int i = 0; i < n; i++) { array[i] = sc.nextInt(); } System.out.println(solution2(array, n)); }}
变形
将上述的数组变成一个环,其他条件保持不变。
- 测试输入
7
4 2 6 1 3 5 8 - 测试输出
17
分析2
对于环的情况,仍然可以利用上述直线的方法完成,只是有一些变化。首先要保证首尾元素不能同时选取,它们也属于相邻元素,这可以通过构造最优解来判断:如果首尾元素同时选取,则删除尾元素而保留首元素;其次为了找到所有可取的情况,需要对数组不断进行循环移位,从每一个元素开始,找出能够取得的最大和。这里对数组的循环移位实际上只需要做两次即可,因为我们求解
代码2
import java.util.Scanner;public class NotAdjacentCircle { static int solution(int[] array, int n) { int[] s = new int[n + 1]; boolean[] isUsed = new boolean[n];// 元素是否使用,用于构造最优解 s[0] = 0; s[1] = array[0]; isUsed[0] = true; for (int i = 2; i < n + 1; i++) { int takei = s[i - 2] + array[i - 1]; int skipi = s[i - 1]; if (takei > skipi) { s[i] = takei; isUsed[i - 1] = true; } else { s[i] = skipi; isUsed[i - 1] = false; } } return makeCircle(s, isUsed, n); } static int makeCircle(int[] s, boolean[] isUsed, int n) { if (!isUsed[n - 1]) return s[n];// 最后一个元素没用,首尾不会相邻 int i = n - 1; boolean isFirstUsed = false;// 第一个元素是否使用 while (i >= 0) {// 构造最优解的过程 if (isUsed[i]) { if (i == 0) isFirstUsed = true; i -= 2; } else { i -= 1; } } return isFirstUsed ? s[n - 1] : s[n];// 如果首尾相邻,则删除尾元素 } static int[] leftShift(int[] array, int steps) { int n = array.length; int[] newArray = new int[n]; System.arraycopy(array, steps, newArray, 0, n - steps); System.arraycopy(array, 0, newArray, n - steps, steps); return newArray; } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int[] array = new int[n]; for (int i = 0; i < n; i++) { array[i] = sc.nextInt(); } int r1 = circleSolution(array, n); array = leftShift(array, 1); int r2 = circleSolution(array, n); r2 = Math.max(r1, r2); array = leftShift(array, 1); int r3 = circleSolution(array, n); r3 = Math.max(r2, r3); System.out.println(r3); }}
- 元素互不相邻的最大和子数组
- 不相邻的最大子数组和
- [LeetCode] House Robber 求数组中元素两两不相邻的子序列最大和
- [LeetCode] House Robber II 求循环数组中元素两两不相邻的子序列最大和
- House Robber I - 由数组中不相邻元素组成的子数组,使其和最大
- 数组中不相邻元素的最大和
- 动态规划求不相邻的最大子数组和
- 动态规划求不相邻的最大子数组和
- 动态规划求不相邻的最大子数组和
- 找出数组中任何相邻子向量的最大和
- 求不相邻的最大子数组和
- 数组最大相邻元素之和
- Ruby实现求数组内相邻元素的最大和-《编程珠玑》问题求解
- 给定一个非负数组,求不相邻元素的最大和。
- 求一个数组中最大的相邻元素之和
- 给一个整数数组,有正有负。找出数组最大和,条件是使用的元素不能有相邻
- angullar ui-href 子元素和父元素的跳转互不影响——阻止冒泡
- 不相邻子序列最大和
- Linux网络编程[DNS解析原理,了解相关DNS解析的函数]
- c#生成安装包程序和卸载程序
- scala实例——六
- 组件化架构漫谈
- 【JSP学习笔记(2)】——JavaScript应用
- 元素互不相邻的最大和子数组
- C6-1 最大子数组和
- hdu 1114 Piggy-Bank(完全背包)
- Mysql SQL查询今天、昨天、n天内、第n天
- 文件超过某个大小就删除(C语言)
- 关于UIScrollView的一点小发现
- 页面静态化
- 【LeetCode】51. N-Queens
- 图片自适应父元素的大小,并左右上下居中