1. 给出一个正整数 N 和长度 L ,找出一段长度大于等于 L 的连续非负整数,他们的和恰好为 N 。答案可能有多个,我我们需要找出长度最小的那个。<br /> 例如 N = 18 L = 2:<br /> 5 + 6 + 7 = 18 <br /> 3 + 4 + 5 + 6 = 18<br />都是满足要求的,但是我们输出更短的 5 6 7 <br />数据范围: 1n109 2L100

    输入描述:
    输入数据包括一行: 两个正整数N(1 ≤ N ≤ 1000000000),L(2 ≤ L ≤ 100)

    输出描述:
    从小到大输出这段连续非负整数,以空格分隔,行末无空格。如果没有这样的序列或者找出的序列长度大于100,则输出No

    思路:等差数列
    https://www.nowcoder.com/questionTerminal/46eb436eb6564a62b9f972160e1699c9

    扩展:和为s的连续正数序列(滑动窗口)
    输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。
    序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。
    输入:target = 9 输出:[[2,3,4],[4,5]]
    思路:移动滑动窗口,维护窗口和sum,左开右闭[left,right),sum与target比较移动左右边界

    class Solution {
        /**
            和为s的连续正数序列: 滑动窗口
            移动滑动窗口,维护窗口和sum,左开右闭[left,right),sum与target比较移动左右边界
         */
        public int[][] findContinuousSequence(int target) {
            int left = 1; // 滑动窗口的左边界
            int right = 1; // 滑动窗口的右边界
            int sum = 0;  // 滑动窗口中数字的和
            List<int[]> result = new ArrayList<>();
            while(left <= target/2){
                if(sum < target){   // 右边界向右移动
                    sum += right;
                    right++;
                }else if(sum > target){   // 左边界向右移动
                    sum -= left;
                    left++;
                }else{   // 记录结果
                    int[] res = new int[right - left];
                    for(int k=left; k < right; k++){
                        res[k-left] = k;
                    }
                    result.add(res);
                    // 左边界向右移动
                    sum -= left;
                    left++;
                }
            }
            return result.toArray(new int[result.size()][]);
        }
    }
    

    扩展2: 给个范围l-n,一个targer,输出所有和为 target 的个数最少的连续正整数序列(至少含有两个数)

    import java.util.*;
    
    /**
       和为s的连续正数序列: 滑动窗口
       移动滑动窗口,维护窗口和sum,左开右闭[left,right),sum与target比较移动左右边界
    */
    public class Main{
        public static void  main(String[] args){
            Scanner sc = new Scanner(System.in);
            int num = sc.nextInt();
            int len = sc.nextInt();
            seq_sum(num,len);
        }
    
        public static int seq_sum(int num, int len){
            int left = len;  // 滑动窗口的左边界
            int right = len + 2;  // 滑动窗口的右边界
            int sum = 2 * len + 1;  // 滑动窗口中数字的和
            Map<Integer,Integer> map = new HashMap<>();
            List<int[]> result = new ArrayList<>();
            while(left <= num / 2){
                if(sum < num){  // 右边界向右移动
                    sum += right;
                    right++;
                }else if(sum > num){  // 左边界向右移动
                    sum -= left;
                    left++;
                }else{   // 记录结果
                    int[] res = new int[right - left];
                    for(int k = left; k < right; k++){
                        res[k-left] = k;
                    }
                    result.add(res);
                    // 左边界向右移动
                    sum -= left;
                    left++;
                }
            }
            int xxx[][] = result.toArray(new int[result.size()][]);
            if(xxx.length == 0){
                System.out.println("No");
                return 0;
            }
            # 求出长度最小的连续正整数序列
            #(HashMap记录每个结果序列的长度,求出在二维的下标,使用StringBuilder构建输出)
            for(int i = 0; i < result.size(); i++){
                map.put(i,xxx[i].length);
            }
            int minlen = 10000;
            for(Integer value : map.values()){  //遍历value求出最小长度
                minlen = Math.min(value.intValue(),minlen);
            }
            int sss = 0;
            for(Integer key : map.keySet()){  //遍历key求出value=minlen的key(二维下标)
                if(map.get(key.intValue()) == minlen)
                    sss = key;
            }
            //构建输出
            StringBuilder stringBuilder = new StringBuilder();
            for (int i = 0; i < xxx[sss].length; i++) {
                stringBuilder.append(xxx[sss][i]);
                stringBuilder.append(" ");
            }
            stringBuilder.deleteCharAt(stringBuilder.length()-1);
            System.out.println(stringBuilder.toString());
            return 0;
        }
    }
    

    HashMap便利的四种方式:

    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.Map;
    /**
     * HashMap 不同遍历方法比较
     */
    public class TestHashMap {
        public static void main(String[] args) {
            Map<Integer,String> map =new HashMap<Integer,String>();
            map.put(1, "xiao");
            map.put(2, "chao");
            map.put(3, "shang");
            map.put(4, "xue");
    
            //方法一
            for(Map.Entry<Integer,String> entry : map.entrySet()) {
                System.out.println("方法一:key ="+entry.getKey()+"---value="+entry.getValue());
            }
    
            //方法二
            for(Integer key:map.keySet()) {
                System.out.println("方法二:key = "+key);
            }
    
            for(String value:map.values()) {
                System.out.println("方法二:value = "+value);
            }
            //方法三
            Iterator<Map.Entry<Integer,String>> entries = map.entrySet().iterator();
            while(entries.hasNext()) {
                Map.Entry<Integer,String> entry = entries.next();
                System.out.println("方法三:key = "+entry.getKey()+"--value="+entry.getValue());
            }
    
            //方法四
            for(Integer key:map.keySet()) {
                String value = map.get(key);
                System.out.println("方法四:Key = " + key + ", Value = " + value);
            }
        }    
    
    }