一.笨阶乘
通常,正整数 n 的阶乘是所有小于或等于 n 的正整数的乘积。例如,factorial(10) = 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1。
相反,我们设计了一个笨阶乘 clumsy:在整数的递减序列中,我们以一个固定顺序的操作符序列来依次替换原有的乘法操作符:乘法(*),除法(/),加法(+)和减法(-)。
例如,clumsy(10) = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1。然而,这些运算仍然使用通常的算术运算顺序:我们在任何加、减步骤之前执行所有的乘法和除法步骤,并且按从左到右处理乘法和除法步骤。
另外,我们使用的除法是地板除法(floor division),所以 10 * 9 / 8 等于 11。这保证结果是一个整数。
实现上面定义的笨函数:给定一个整数 N,它返回 N 的笨阶乘。
输入:4
输出:7
解释:7 = 4 * 3 / 2 + 1
输入:10
输出:12
解释:12 = 10 * 9 / 8 + 7 - 6 * 5 / 4 + 3 - 2 * 1
(1)开始我一看到这个题直接就设置一个数组存放加减乘除,直接循环就行,但是他会有优先级的错误,因为题中要求是我一序列列下来在计算,就会先算乘除再算加减,而我的算法会一个个算就错了
(2)过一会想到了加减乘除4个计算为一个循环,在进行总和.看注释.
public int clumsy(int N) {
int count = 0;
//看有几个循环.就算几次,
int times = N / 4 + ((N % 4 == 0)? 0 : 1);
int[] arr = new int[times];
int sum = 0;
int m = N;
//一次循环,加减乘除全算了
//在我们这种思想下10 * 9 / 8 + 7这为一次循环,但是后面 + 7这一个本来是加在总和上的
//但最后成了减了,所以索性直接全减了,最后只补偿第一个要加的就行了.
for(int i = 0; i < times; i++){
arr[i] = N;
if(count == 0 && N > 1){
arr[i] = arr[i] * (N - 1);
count++;
N--;
}
if(count == 1 && N > 1 ){
arr[i] = arr[i] / (N - 1);
count++;
N--;
}
if(count == 2 && N > 1){
arr[i] = arr[i] - (N - 1);
count++;
N--;
}
//第一次循环只需要赋值,第二次开始开始减
if(i == 0){
sum = arr[i];
}else{
sum = sum - arr[i];
}
count = 0;
N--;
}
//补偿第一次的减.
if(m > 3){
sum = sum + (m - 3) * 2;
}
return sum;
}
二.等差数列划分
如果一个数列至少有三个元素,并且任意两个相邻元素之差相同,则称该数列为等差数列。
例如,以下数列为等差数列:
1, 3, 5, 7, 9
7, 7, 7, 7
3, -1, -5, -9
1.一看到这题,不就是直接暴力搜索就ok了?
2.在细想一下,是不是可以优化一下,他第一层循环,循环开始,第二层循环就是至少3层到数组末尾,第三次循环看从开始的第一个到第二层循环末尾是否相等.那么第二层循环每次都加一个数,那么就没必要从头开始比较了,只要相等,就比较每次加进来的那个数就行了。
public int numberOfArithmeticSlices(int[] A) {
// int count = 0;
//遍历头
// for(int i = 0; i < A.length - 2; i++){
// int d = A[i + 1] - A[i];
//从头的第三个数开始往后,找满足的
// for(int j = i + 2; j < A.length; j++){
// int z;
//去看满足等差数列不.
// for(z = i + 1; z <= j; z++){
// if(A[z] - A[z - 1] != d){
// break;
// }
// }
// if(z > j){
// count++;
// }
// }
// }
// return count;
int count = 0;
for(int i = 0; i < A.length - 2; i++){
int d = A[i + 1] - A[i];
for(int j = i + 2; j < A.length; j++){
if(A[j] - A[j - 1] != d){
break;
}else{
count++;
}
}
}
return count;
}
三.字母异位词分组
给定一个字符串数组,将字母异位词组合在一起。字母异位词指字母相同,但排列不同的字符串。
输入: [“eat”, “tea”, “tan”, “ate”, “nat”, “bat”],
输出:
[
[“ate”,“eat”,“tea”],
[“nat”,“tan”],
[“bat”]
]
1.开始我想的是把每个字符串的ascll值算出来,看有相等的就放到一起,但是不同的字符串也有ascll值相等的就over了
2.可以创建一个哈希map 存的(排好序的字符串, 放的字符顺序表)先去遍历字符串数组,字符串进来就转成字符数组,排序,再转为字符串,看map中有没有key值,有就拿出来把这个值加进去,没有就创建新的key-value遍历一遍就OK了
public List<List<String>> groupAnagrams(String[] strs) {
if(strs.length == 0){
return new ArrayList();
}
Map<String, List> map = new HashMap<String, List>();
//遍历字符串数组
for(String s : strs){
char[] ca = s.toCharArray();
Arrays.sort(ca);
String key = String.valueOf(ca);
if(!map.containsKey(key)){
map.put(key, new ArrayList());
}
map.get(key).add(s);
}
return new ArrayList(map.values());
}