求数组中和为给定值的所有子序列

2017年网易游戏的一道编程题,大致意思是满足组合攻击技能,必须是所选择时技能的和为m(m>0),且所选的这些技能的乘积最大:

分解后主解决两个问题:

其一:求数组中和为m的所有子数组;

其二:在满足一的条件下,求所有子数组的最大值;

主要考察的还是如何求数组中和为m的所有子数组:

如:数组[1,2,3,4,5,6],m=7时,满足条件的子数组有[1,2,4],[3,4],[2,5],[1,6];

主要使用回溯法解决该问题,思路以后补上:

import java.util.ArrayList;
import java.util.Scanner;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub

        Scanner scanner = new Scanner(System.in);
        while(scanner.hasNext()){
            String array = scanner.nextLine();
            int m = scanner.nextInt();
            String[] strings = array.trim().split(" ");
            int len = strings.length;
            int[] num = new int[len];
            for(int i=0;i<len;i++){
                num[i] = Integer.parseInt(strings[i]);
            }
            int[] record = new int[len];
            ArrayList<ArrayList<Integer>> lists =new ArrayList<ArrayList<Integer>>();
            backtrack(num,record,m,0,0,lists);
            System.out.println(maxFighting(lists));
        }
    }
  //求数组input中,和为给定key的所有子数组
    public static void backtrack(int[] input,int[] record,int key,
            int sum,int n,ArrayList<ArrayList<Integer>> lists) {
        if(n == input.length){
            return;
        }else{
            for(int i=0; i<=1; i++){
                sum += i*input[n];
                record[n] = i;
                if(sum == key){
                    ArrayList<Integer> list = new ArrayList<Integer>();
                    for(int j=0; j<=n; j++){
                        if(record[j]==1){
                            list.add(input[j]);
                        }
                    }
                    lists.add(list);
                }
                if(sum<key){
                    backtrack(input, record, key, sum, n+1,lists);
                }
                sum -= i*input[n];
            }
        }
    }    //求所有子数组中,最大乘积
    public static int maxFighting(ArrayList<ArrayList<Integer>> lists){
        int size = lists.size();
        if(lists==null||size==0)
            return -1;
        int maxMultipy = Integer.MIN_VALUE;
        int multipy = 1;
        for(int i=0;i<size;i++){
            ArrayList<Integer> list = lists.get(i);
            for(int j=0;j<list.size();j++){
                multipy *=list.get(j);
            }
            if(multipy>maxMultipy){
                maxMultipy = multipy;
            }
            multipy = 1;
        }
        return maxMultipy;
    }

}
时间: 2024-10-12 20:48:07

求数组中和为给定值的所有子序列的相关文章

求数组中和为给定值的任意两个数

转载请注明出处:http://blog.csdn.net/ns_code/article/details/24933341     题目: 输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字.要求时间复杂度是O(n).如果有多对数字的和等于输入的数字,输出任意一对即可. 例如输入数组1.2.4.7.11.15和数字15.由于4+11=15,因此输出4和11.     思路: 最直接的做法是暴力法,两个for循环,时间复杂度为O(n*n),但是这样没有充

10.排序数组中和为给定值的两个数字

http://zhedahht.blog.163.com/blog/static/2541117420072143251809/ 题目:输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字.要求时间复杂度是O(n).如果有多对数字的和等于输入的数字,输出任意一对即可. 例如输入数组1.2.4.7.11.15和数字15.由于4+11=15,因此输出4和11. 分析:如果我们不考虑时间复杂度,最简单想法的莫过去先在数组中固定一个数字,再依次判断数组中剩下的n

求二叉树中和为给定值的所有路径

转自:http://blog.csdn.net/lalor/article/details/7614381 问题定义: You are given a binary tree in which each node contains a value. Design an algorithm to print all paths which sum up to that value. Note that it can be any path in the tree-it does not have

找出升序数组中和为给定值的两个数字

输入一个已经按升序排序过的数组和一个数字,在数组中查找两个数,使得它们的和正好是输入的那个数字.如果有多对数字的和等于输入的数字,输出任意一对即可. 详细描述: 接口说明 原型: bool FindTwoNumbersWithSum(int aData[], unsignedint uiLength, int sum, int *pNum1, int *pNum2); 输入参数: int aData[]           // 升序数组 unsigned int uiLength // 数组元

[程序员面试题精选100题]10.排序数组中和为给定值的两个数字

扩展(1):输入一个数组,判断这个数组中是不是存在三个数字i, j, k,满足i+j+k等于0. 扩展(2):如果输入的数组是没有排序的,但知道里面数字的范围,其他条件不变,如何在O(n)时间里找到这两个数字?这个的基本思路是先用哈希表实现O(n)的排序(请参照本面试题系列的第57题),接下来的步骤都一样了.

[程序猿面试题精选100题]10.排序数组中和为给定值的两个数字

剑指Offer之和为S的两个数字 剑指Offer之和为S的连续正数序列 扩展(1):输入一个数组,推断这个数组中是不是存在三个数字i, j, k,满足i+j+k等于0. 扩展(2):假设输入的数组是没有排序的,但知道里面数字的范围,其它条件不变,怎样在O(n)时间里找到这两个数字?这个的基本思路是先用哈希表实现O(n)的排序(请參照本面试题系列的第57题).接下来的步骤都一样了.

[LeetCode]1. Two Sum 数组中和为特定值的两个数

Given an array of integers, find two numbers such that they add up to a specific target number. The function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that

求数组中和为0的最大子数组

#include<map> #include<iostream> #include<vector> #include<set> using namespace std; void get(vector<int> a) { vector<int> num; int i = 0; map<int, int> ma; num.push_back(0); num.push_back(a[0]); for (i = 1; i <

(回溯法)数组中和为S的N个数

Given a list of numbers, find the number of tuples of size N that add to S. for example in the list (10,5,-1,3,4,-6), the tuple of size 4 (-1,3,4,-6) adds to 0. 题目: 给一数组,求数组中和为S的N个数 思路: 回溯法,数组中每个数都有两种选择,取或者不取: 当选择的数等于N时,则判断该数之和是否等于S. 代码: #include <io