求1+2+…+n Java逻辑符短路 + 和为s的连续正数序列

110 阅读1分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 23 天,点击查看活动详情

1 求1+2+…+n Java逻辑符短路

一、题目描述

求 1+2+...+n ,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)。

示例 1:

输入: n = 3

输出: 6

示例 2:

输入: n = 9

输出: 45

限制:

1 <= n <= 10000

二、思路讲解

1、不能使用首尾相加求平均值的方式,因为不能用除法;

2、不能使用循环相加的方式,因为不能用for、while;

3、递归的跳出判断需要使用 if 等条件判断

思考之后发现,还是应该使用递归,难点在于使用什么来代替条件判断,时递归在n=1的时候跳出。

答案是逻辑符的短路问题:例如:if (A && B),当A不满足的时候,就不会走B。那么我们可以在A处判断n是否为1,而将递归入口放在B处,当A不满足,B处的递归就不会走入,从而终止递归。像这样 n > 1 && sumNums(n-1)>0,当n==1时,就不会走入后面的递归。

三、Java代码实现

class Solution {
 
    int sum = 0;
 
    public int sumNums(int n) {
        boolean temp = (n>1 && sumNums(n-1)>0);
        sum = sum + n;
        return sum;
    }
}

2.和为s的连续正数序列

一、题目描述

输入一个正整数 target ,输出所有和为 target 的连续正整数序列(至少含有两个数)。

序列内的数字由小到大排列,不同序列按照首个数字从小到大排列。

示例 1:

输入:target = 9

输出:[[2,3,4],[4,5]]

示例 2:

输入:target = 15

输出:[[1,2,3,4,5],[4,5,6],[7,8]]

限制:

1 <= target <= 10^5

二、思路讲解

很容易想到双指针滑动窗口。i,j两个指针构成窗口,i在前j在后,从1开始向后滑动,1 2 3 4……。若窗口内数字的和小于target,j后移,扩大窗口;若大于target,i后移,缩小窗口。

三、Java代码实现

class Solution {
 
    public int[][] findContinuousSequence(int target) {
 
        int i=1, j=1;
        int sum = 1;
        List<int []> list = new ArrayList<>();
        while(i<=(target/2+1)) {
            while(sum<=target) {
                j++;
                sum = sum + j;
                if(sum==target) {
                    int []temp = new int[j-i+1];
                    for (int k=0; k<temp.length; k++) {
                        temp[k] = i+k;
                    }
                    list.add(temp);
                    break;
                }
            }
            while(i<=(target/2+1) && sum>=target) {
                sum = sum - i;
                i++;
                if(sum==target) {
                    int []temp = new int[j-i+1];
                    for (int k=0; k<temp.length; k++) {
                        temp[k] = i+k;
                    }
                    list.add(temp);
                    break;
                }
            }
        }
        return list.toArray(new int[0][]);
    }
}

更简洁的代码,核心思想是一样的,复杂度也相同:

class Solution {
    public int[][] findContinuousSequence(int target) {
        int i = 1, j = 2, s = 3;
        List<int[]> res = new ArrayList<>();
        while(i < j) {
            if(s == target) {
                int[] ans = new int[j - i + 1];
                for(int k = i; k <= j; k++)
                    ans[k - i] = k;
                res.add(ans);
            }
            if(s >= target) {
                s -= i;
                i++;
            } else {
                j++;
                s += j;
            }
        }
        return res.toArray(new int[0][]);
    }
}