zoukankan      html  css  js  c++  java
  • 关于一个数组的算法问题

    那天去面试,做到了一题笔试题。题目看上去很简单。具体如下:就是有一个数组,内容随机,长度不定,要求把他分成两个子数组,使得这两个子数组的和最接近(当然原题是差最小)。我给出的思路是这样的:①算出大数组和的一半A②将数组排序后取第一个值B③对数组做循环,从i=0开始,判断B是否小于等于A,如果是,则取i+1的数+B判断是否小于等于A,如果是则继续判断,直至i+1的数加上后超出A,此时子数组1即为0-i的值,剩下子数组2即为i+1以后的值。当初我也不知道对不对,总感觉思路不对,于是在答题的结尾还补了一句思路可能不对。后来结束后我去网上查了下,给出的方案大体一致,不同的是并没有对原数组进行排序。核心思想也是:在array中选取若干个元素,使得这些元素的和<=sum/2,且是最接近sum/2的元素集合。方法也有不同,网上给出的是

    建一个数组:int[][]f=new int[length+1][sum/2+1]

    状态方程:f[i][j]=Max(f[i-1][j-array[i]]+array[i],f[i-1][j])

    解释:f[i][j]表示array中i个元素的和<=j,且是最接近j的元素集合。f[i-1][j-array[i]]表示array中i-1个元素的和最接近j-array[i],所以f[i][j]应该是[i-1][j-array[i]]+array[i]和f[i-1][j]中最大的那个。有点像0-1背包问题。

     1 public class DivideArrayTest {  
     2   
     3     /** 
     4      * @param args 
     5      */  
     6     public static void main(String[] args) {  
     7         // TODO Auto-generated method stub  
     8         int[] array = { 1, 0, 1, 7, 2, 4 };  
     9         System.out.println(getMaxDiff(array));  
    10   
    11     }  
    12   
    13     /* f[i][j]表示i个元素装容量为j的背包能装的最大容量 */  
    14     public static int getMaxDiff(int[] array) {  
    15         int sum = getSum(array);  
    16         int length = array.length;  
    17         int[][] f = new int[length + 1][sum / 2 + 1];  
    18         for (int i = 0; i < length; i++) {  
    19             for (int j = 1; j <= sum / 2; j++) {  
    20                 f[i + 1][j] = f[i][j];  
    21                 if (array[i] <= j && f[i][j - array[i]] + array[i] > f[i][j]) {  
    22                     f[i + 1][j] = f[i][j - array[i]] + array[i];  
    23                 }  
    24             }  
    25         }  
    26         return sum - 2 * f[length][sum / 2];  
    27     }  
    28   
    29     public static int getSum(int[] array) {  
    30         int sum = 0;  
    31         for (int i = 0; i < array.length; i++) {  
    32             sum += array[i];  
    33         }  
    34         return sum;  
    35     }  
    36   
    37 }  

    说实话,不是很理解,我觉得按我的方式是否更加好一点呢?

  • 相关阅读:
    [apue] FIFO:不是文件的文件
    [apue] 等待子进程的那些事儿
    [apue] popen/pclose 疑点解惑
    [apue] 使用 popen/pclose 的一点疑问
    [apue] 使用 poll 检测管道断开
    [apue] dup2的正确打开方式
    [apue] 管道原子写入量的一个疑问
    [apue] 测试管道容量的一些疑问
    【新阁教育】再也不用担心我的PLC通信不上了
    【新阁教育】三菱PLC的这个功能,真的很强大
  • 原文地址:https://www.cnblogs.com/timePasser-leoli/p/8583704.html
Copyright © 2011-2022 走看看