第四十六题:
求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句(A?B:C)
思路:
1.需利用逻辑与的短路特性实现递归终止。
2.当n==
0
时,(n>
0
)&&((sum+=Sum_Solution(n-
1
))>
0
)只执行前面的判断,为
false
,然后直接返回
0。
3.当n>
0
时,执行sum+=Sum_Solution(n-
1),实现递归计算Sum_Solution(n)。
代码:
public class Solution {
public int Sum_Solution(int n) {
int sum = n;
boolean ans = (n>0)&&((sum+=Sum_Solution(n-1))>0);
return sum;
}
}
--------------------------------------------------------------------可爱的分界线-----------------------------------------------------------------------------------
第四十七题:
写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。
思路:
- 两个数异或:相当于每一位相加,而不考虑进位;
- 两个数相与,并左移一位:相当于求得进位
- 将上述两步的结果相加(即异或)
代码:
public class Solution {
public int Add(int num1,int num2) {
while( num2!=0 ){
int sum = num1 ^ num2;
int carray = (num1 & num2) << 1;
num1 = sum;
num2 = carray;
}
return num1;
}
}
--------------------------------------------------------------------可爱的分界线-----------------------------------------------------------------------------------
第四十八题:
将一个字符串转换成一个整数(实现Integer.valueOf(string)的功能,但是string不符合数字要求时返回0),要求不能使用字符串转换整数的库函数。 数值为0或者字符串不是一个合法的数值则返回0。
思路:数组实现
代码:
public class Solution {
public static boolean flag;
public static int StrToInt(String str) {
flag = false; //判断输入是否合法
if (str == null || str.trim().equals(""))
{
flag = true;
return 0;
}
// symbol=0,说明该数为正数;symbol=1,该数为负数;start用来区分第一位是否为符号位
int symbol = 0;
int start = 0;
char[] chars = str.trim().toCharArray();
if (chars[0] == '+') {
start = 1;
} else if (chars[0] == '-') {
start = 1;
symbol = 1;
}
int result = 0;
for (int i = start; i < chars.length; i++) {
if (chars[i] > '9' || chars[i] < '0') {
flag = true;
return 0;//异常就直接返回
}
result=result * 10 + (int) (chars[i] - '0');
}
result = (int) Math.pow(-1, symbol) * result;
return result;
}
}
--------------------------------------------------------------------可爱的分界线-----------------------------------------------------------------------------------
第四十九题:
在一个长度为n的数组里的所有数字都在0到n-1的范围内。 数组中某些数字是重复的,但不知道有几个数字是重复的。也不知道每个数字重复几次。请找出数组中任意一个重复的数字。 例如,如果输入长度为7的数组{2,3,1,0,2,5,3},那么对应的输出是第一个重复的数字2。
思路:利用 HashSet 解决,从头到尾扫描数组,每次扫描到一个数,判断当前数是否存在 HashSet 中,如果存在,则重复,对 duplication 赋值返回,否则将该数加入到 HashSet 中
代码:
// Parameters:
// numbers: an array of integers
// length: the length of array numbers
// duplication: (Output) the duplicated number in the array number,length of duplication array is 1,so using duplication[0] = ? in implementation;
// Here duplication like pointor in C/C++, duplication[0] equal *duplication in C/C++
// 这里要特别注意~返回任意重复的一个,赋值duplication[0]
// Return value: true if the input is valid, and there are some duplications in the array number
// otherwise false
import java.util.*;
public class Solution {
public boolean duplicate(int numbers[],int length,int [] duplication) {
Set<Integer> set = new HashSet<>();
for(int i =0 ;i<length;i++){
if(set.contains(numbers[i])){
duplication[0] = numbers[i];
return true;
}else{
set.add(numbers[i]);
}
}
return false;
}
}
--------------------------------------------------------------------可爱的分界线-----------------------------------------------------------------------------------
第五十题:
给定一个数组A[0,1,...,n-1],请构建一个数组B[0,1,...,n-1],其中B中的元素B[i]=A[0]*A[1]*...*A[i-1]*A[i+1]*...*A[n-1]。不能使用除法。
思路:
B[i]的值可以看作下图的矩阵中每行的乘积。
下三角用连乘可以很容求得,上三角,从下向上也是连乘。
因此我们的思路就很清晰了,先算下三角中的连乘,即我们先算出B[i]中的一部分,然后倒过来按上三角中的分布规律,把另一部分也乘进去。
代码:
代码:
import java.util.ArrayList;
public class Solution {
public int[] multiply(int[] A) {
int length = A.length;
int[] B = new int[length];
if(length != 0 ){
B[0] = 1;
//计算下三角连乘
for(int i = 1; i < length; i++){
B[i] = B[i-1] * A[i-1];
}
int temp = 1;
//计算上三角
for(int j = length-2; j >= 0; j--){
temp *= A[j+1];
B[j] *= temp;
}
}
return B;
}
}
--------------------------------------------------------------------可爱的分界线-----------------------------------------------------------------------------------