将大多数短语提取到X个单词

时间:2017-11-28 18:47:10

标签: java arrays algorithm

我有一个有趣的算法/ java问题,我认为我"击败"并且非常简单但事实证明我没有得到所需的输出:

你有一串短语。为简单起见,请将它们视为整数长度。

String s ="我是汤姆" 将作为[1,2,3]存储在整数数组中,其中每个数组表示字符串中每个单词的长度。

编写一个方法来计算最长的子序列,使其小于或等于给定的k值。

Input: 
3 //length of array 
1 //a[0] 
2 //a[1] 
3 //a[2] 
4 // value of k 

Output: 
2 

Input: 
4 //length of array 
3 
1 
2 
1 
4 //value of k 

Output: 
3 

我最初的想法是可以的,这非常简单,我要对这个数组进行排序(没有说明你不能)并且理论上所有最小的数字应该是第一个。通过索引运行数组索引,将它们相加,直到<= k不再为真。然后我针对给定的测试运行它,它通过前2个并且在3日失败。这是我的排序和添加代码:

// k is the number we want to sum the phrases up to
// a is the length of a phrase
// Need to add phrases together to get the most phrases less than or equal to k
// Algorithm: Probably want to sort the list then add from the front until > k
static int maxLength(int[] a, int k) {
    int sum = 0;
    int numPhrases = 0;

    Arrays.sort(a);

    for(int i = 0; i < a.length; i++) {

        if((sum + a[i]) <= k) {
            sum += a[i];
            numPhrases++;
        }

    }

    return numPhrases;
}

我们获得了以下无法编辑的代码(以及导入):

public static void main(String[] args) throws IOException{
        Scanner in = new Scanner(System.in);
        final String fileName = System.getenv("OUTPUT_PATH");
        BufferedWriter bw = new BufferedWriter(new FileWriter(fileName));
        int res;

        int _a_size = 0;
        _a_size = Integer.parseInt(in.nextLine().trim());
        int[] _a = new int[_a_size];
        int _a_item;
        for(int _a_i = 0; _a_i < _a_size; _a_i++) {
            _a_item = Integer.parseInt(in.nextLine().trim());
            _a[_a_i] = _a_item;
        }

        int _k;
        _k = Integer.parseInt(in.nextLine().trim());

        res = maxLength(_a, _k);
        bw.write(String.valueOf(res));
        bw.newLine();

        bw.close();
}

这基本上完成了所有工作,只是给你数字k(你可以添加的单词)和你正在添加的数字数组。

它打破了以下测试:

Input:
61
74    
659    
931    
273
545
879
924
710   
441   
166   
493  
43   
988   
504   
328  
730   
841  
613   
304  
170 
710  
158 
561  
934  
100 
279  
817 
336
98 
827 
513
268
811
634
980
150
580
822
968
673
394
337
486
746
229
92
195
358
2
154
709
945
669
491
125
197
531
904
723
667
550
22337

预期输出为46

我的程序在此处输出51

感谢您的帮助,我很困惑为什么这不正确。

1 个答案:

答案 0 :(得分:0)

阅读声明后,

解决方案位于: http://www.geeksforgeeks.org/longest-subarray-sum-elements-atmost-k/

static int maxLength(int[] arr, int k) {
    int sum = 0;
    int cnt = 0, maxcnt = 0;

    for (int i = 0; i < arr.length; i++) {

        // If adding current element doesn't
        // cross limit add it to current window
        if ((sum + arr[i]) <= k) {
            sum += arr[i];
            cnt++;
        }

        // Else, remove first element of current
        // window.
        else if (sum != 0) {
            sum = sum - arr[i - cnt] + arr[i];
        }

        // keep track of max length.
        maxcnt = Math.max(cnt, maxcnt);
    }
    return maxcnt;
}

一种有效的方法是使用滑动窗口技术。

  • 遍历数组并检查添加当前元素是否小于或等于k。
  • 如果小于k,则将其添加到总和并增加计数。
  • 否则 删除子阵列的第一个元素并减少计数。 再次检查是否在添加当前元素时其总和小于或等于k。 如果它小于k,则将其添加到sum并增加计数。
  • 跟踪最大数量。

这是正确的解决方案。

希望这有帮助!