开启掘金成长之旅!这是我参与「掘金日新计划 · 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][]);
}
}