题目描述:

给定一个数组,判断数组内是否存在一个连续区间,使其和恰好等于给定整数k。

输入:

输入包含多组测试用例,每组测试用例由一个整数n(1<=n<=10000)开头,代表数组的大小。

接下去一行为n个整数,描述这个数组,整数绝对值不大于100。

最后一行为一个整数k(大小在int范围内)。

输出:

对于每组测试用例,若存在这个连续区间,输出其开始和结束的位置,s,e(s <= e)。

若存在多个符合条件的输出,则输出s较小的那个,若仍然存在多个,输出e较小的那个。

若不存在,直接输出"No"。

样例输入:
5
-1 2 3 -4 9
5
3
-1 2 -3
7
2
-1 1
0
样例输出:
2 3
No
1 2
来源:
2014年王道论坛计算机考研机试全真模拟考试
我的解答:
package jobdu.wangdao;

import java.util.Scanner;

/**
* 题目描述: 给定一个数组,判断数组内是否存在一个连续区间,使其和恰好等于给定整数k。
*
*/
public class Question1554 { private static void solve(int[] array, int k) {
boolean find = false;
for (int i = 0; i < array.length; i++) {
if (!find) {
int sum = 0;
for (int j = i; j < array.length; j++) {
sum += array[j];
if (sum == k) {
find = true;
System.out.println((i + 1) + " " + (j + 1));
break;
}
}
}
}
if (!find)
System.out.println("No");
} public static void main(String[] args) { @SuppressWarnings("resource")
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
int n = scanner.nextInt();
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = scanner.nextInt();
}
int k = scanner.nextInt();
solve(array, k);
}
}
}

  这个解答用的是暴力o(n*n)破解,提交后九道提示超时。

  用动态规划的思想,记录从a[0]开始到a[i]的和存入sum[i],那么当sum[i]-sum[j]=k的时候从a[j+1]到a[i]的和就为k。

package jobdu.wangdao;

import java.io.IOException;
import java.io.StreamTokenizer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map; /**
* 题目描述: 给定一个数组,判断数组内是否存在一个连续区间,使其和恰好等于给定整数k。
*
*/
public class Question1554 { /**
* 暴力求和比较
*
* @param array
* @param k
* @return
*/
public static Section solve(int[] array, int k) {
boolean find = false;
for (int i = 0; i < array.length; i++) {
if (!find) {
int sum = 0;
for (int j = i; j < array.length; j++) {
sum += array[j];
if (sum == k) {
find = true;
System.out.println((i + 1) + " " + (j + 1));
return new Section(i + 1, j + 1);
}
}
}
}
if (!find)
System.out.println("No");
return null;
} public static Section solve2(int[] array, int k) {
int[] sumList = new int[array.length];// 先计算出前0-i个数的和存入sumList
Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
// 记录前i个数的和和值相同的下标
int sum = 0;
for (int i = 0; i < array.length; i++) {
sum = sum + array[i];
sumList[i] = sum;
if (map.containsKey(sum)) {// 将和的下标存入map
List<Integer> indexList = map.get(sum);
indexList.add(i);
} else {
List<Integer> indexList = new ArrayList<Integer>();
indexList.add(i);
map.put(sum, indexList);
}
} boolean find = false;
List<Section> list = new ArrayList<Section>();
for (int j = 0; j < sumList.length; j++) {
int sumi = sumList[j];// 当前遍历的前j个数的和为sumi
if (sumi == k) {// 如果前j个数的和就是k,那么直接为一组解
Section node = new Section(1, (j + 1));
list.add(node);// 加入解集合
find = true;
continue;
}
int temp = sumi + k;// 计算出对应的和已保证a[i]-a[j]=k
if (map.containsKey(temp) && map.get(temp).size() > 0) {
// 如果存在a[i]-a[j]=k,那么从第j+1个数到第i个数之和就为k,这里下标从0开始
int start = j + 2;
int end = -1;
for (Integer integer : map.get(temp)) {// 从和相同的下标中选离j最近比i大的下标作为最后的解
if (integer >= j) {
end = integer + 1;
break;
}
}
if (end >= 0) {
list.add(new Section(start, end));
find = true;
}
}
} if (!find)
System.out.println("No");
else {
Collections.sort(list);// 对可能的解做一次排序,找到符合题意的解
Section section = list.get(0);
System.out.println(section.start + " " + section.end);
return section;
}
return null;
} /**
* 确保List的排序
*
*/
public static class Section implements Comparable<Section> {
int start, end; public Section(int start, int end) {
this.start = start;
this.end = end;
} @Override
public int compareTo(Section o) {
if (this.start == o.start)
return this.end - o.end;
return this.start - o.start;
} } public static void main(String[] args) throws IOException { @SuppressWarnings("deprecation")
StreamTokenizer st = new StreamTokenizer(System.in);
while (st.nextToken() != StreamTokenizer.TT_EOF) {
int n = (int) st.nval;
int[] array = new int[n];
for (int i = 0; i < n; i++) {
st.nextToken();
array[i] = (int) st.nval;
}
st.nextToken();
int k = (int) st.nval;
solve2(array, k);
}
}
}

  其中一开始使用Scanner的方法作为输入,优化许久还是超时,查看其它成功代码采用的是StreamTokenizer方式作为输入。也改为StreamTokenizer方式后,提交通过。

OJ-2:区间问题【九度1554】的更多相关文章

  1. 【九度OJ】题目1065:输出梯形 解题报告

    [九度OJ]题目1065:输出梯形 解题报告 标签(空格分隔): 九度OJ [LeetCode] http://ac.jobdu.com/problem.php?pid=1065 题目描述: 每组测试 ...

  2. 【九度OJ】题目1431:Sort 解题报告

    [九度OJ]题目1431:Sort 解题报告 标签(空格分隔): 九度OJ [LeetCode] http://ac.jobdu.com/problem.php?pid=1431 题目描述: 给你n个 ...

  3. 九度oj 题目1087:约数的个数

    题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...

  4. 九度OJ 1502 最大值最小化(JAVA)

    题目1502:最大值最小化(二分答案) 九度OJ Java import java.util.Scanner; public class Main { public static int max(in ...

  5. 九度OJ,题目1089:数字反转

    题目描述: 12翻一下是21,34翻一下是43,12+34是46,46翻一下是64,现在又任意两个正整数,问他们两个数反转的和是否等于两个数的和的反转. 输入: 第一行一个正整数表示测试数据的个数n. ...

  6. 九度OJ 1500 出操队形 -- 动态规划(最长上升子序列)

    题目地址:http://ac.jobdu.com/problem.php?pid=1500 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往 ...

  7. 九度OJ 1531 货币面值(网易游戏2013年校园招聘笔试题) -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1531 题目描述: 小虎是游戏中的一个国王,在他管理的国家中发行了很多不同面额的纸币,用这些纸币进行任意的组合可以在 ...

  8. 九度OJ 1024 畅通工程 -- 并查集、贪心算法(最小生成树)

    题目地址:http://ac.jobdu.com/problem.php?pid=1024 题目描述:     省政府"畅通工程"的目标是使全省任何两个村庄间都可以实现公路交通(但 ...

  9. 九度OJ 1371 最小的K个数 -- 堆排序

    题目地址:http://ac.jobdu.com/problem.php?pid=1371 题目描述: 输入n个整数,找出其中最小的K个数.例如输入4,5,1,6,2,7,3,8这8个数字,则最小的4 ...

随机推荐

  1. ByPass Mode(略过模式或旁路模式)

    参考: 1. https://baike.baidu.com/item/%E6%97%81%E8%B7%AF%E6%A8%A1%E5%BC%8F/3120563 2. https://zhidao.b ...

  2. regsvr32 bypass windows defender 新思路

    原文链接:blog 在对regsvr32的用法进行了解之后,对于Casey Smith的远程js脚本执行命令的思路很感兴趣. 命令语法如下: regsvr32 /s /n /u /i:http://1 ...

  3. Nuxt+Vue聊天室|nuxt仿微信App界面|nuxt.js聊天实例

    一.项目简述 nuxt-chatroom 基于Nuxt.js+Vue.js+Vuex+Vant+VPopup等技术构建开发的仿微信|探探App界面社交聊天室项目.实现了卡片式翻牌滑动.消息发送/emo ...

  4. spring boot:shardingsphere多数据源,支持未分表的数据源(shardingjdbc 4.1.1)

    一,为什么要给shardingsphere配置多数据源? 1,shardingjdbc默认接管了所有的数据源, 如果我们有多个非分表的库时,则最多只能设置一个为默认数据库, 其他的非分表数据库不能访问 ...

  5. ansible的copy模块应用(ansible 2.9.5)

    一,copy模块的作用: 复制文件到受控的远程主机 说明:刘宏缔的架构森林是一个专注架构的博客,地址:https://www.cnblogs.com/architectforest 对应的源码可以访问 ...

  6. Linux+Nginx/Apache下的PHP exec函数执行Linux命令

    1.php.ini配置文件 打开PHP的配置文件,里面有一行 disable_function 的值,此处记录了禁止运行的函数,在里面将exec和shell_exec.system等函数删除. 2.权 ...

  7. mongodb安装及使用

    安装命令: sudo apt-get install mongodb 开始认证,创建用户: 编辑配置文件: sudo vim /etc/mongodb.conf 11行中的 bind_ip值 修改成为 ...

  8. Windows(WSL2) Linux子系统搭建Docker环境

    摘要:本文主要介绍了如何再Windows(WSL2)中启用Linux系统中,并搭建Docker环境. WSL是适用于 Linux 的 Windows 子系统可让开发人员按原样运行 GNU/Linux ...

  9. mysql explain 查询处理的结果详解

    本文转自 https://blog.csdn.net/boss_way/article/details/91416887 在日常工作中,我们会有时会开慢查询去记录一些执行时间比较久的SQL语句,找出这 ...

  10. Helium文档7-WebUI自动化-highlight高亮显示元素

    前言 highlight方法是通过红框高亮显示元素,在调试中有很大优势,可以清楚看到定位的元素位置 入参介绍 def highlight(element):   """ ...