189轮转数组
/该题可以暴力枚举,但是超时,我还在这说一下
//1.暴力做法为先一个for循环控制向右轮转的个数,然后取出最后一个索引的数
//值放在变量里面,然后第二个循环从后往前遍历(注意这里不能从前往后遍历
//例如第一个索引的值为一赋值给后一个索引的值,再下一个外层循环遍历的时候
//这个后一个索引也会把一赋值给下一个索引的值这样除了第一个索引,其他都时
//第一个索引的值)正确的做法是,从后往前将倒数第二个索引的值赋值给倒数第一个
//倒数第三个赋值给倒数第二个,在循环前把倒数第一个元素放到第一个元素完成一次轮转
//2.还有一种高效率的方法,先将整个数组翻转,再翻转前k个元素,然后翻转剩
//余元素,完成数组的轮转,原理按我的理解差不多因为轮转后,结尾的数组
//会根据k的值跑到对应开头的某个位置,所以翻转数组再翻转前k个元素
//刚好得到尾元素跑到的对应的位置,而起始位置也会根据length-k的值
//翻转回到对应位置
class Solution {
public void rotate(int[] nums, int k) {
k = k % nums.length; // 防止 k 大于数组长度
reverse(nums, 0, nums.length - 1); // 反转整个数组
reverse(nums, 0, k - 1); // 反转前 k 个元素
reverse(nums, k, nums.length - 1); // 反转剩下的元素
}
private void reverse(int[] nums, int start, int end) {
while (start < end) {
int temp = nums[start];
nums[start] = nums[end];
nums[end] = temp;
start++;
end--;
}
}
}
238除自身以外数组的乘积
//此题开始可以计算所有元素的乘积,然后除对给定数组的每个元素x,放入
//answer中此时数组便是答案,但是如果给定数组里面有0,此方法失效
//这里还有第二种方法左右乘积列表,先初始化两个空数组,L和RL[i]表示的是i左侧所有数字的乘积,而R[i]表示的是i右侧所有数字的乘积
//然后用两个循环来填充L,R,数组的值L[0]是1,这样L[i]=L[i-1]*nums[i-1],而对应右数组,因为是从右往左变量R[i]=R[i+1]*nums[i+1]
//最后一个循环用来求除自己以外的所有数组的乘积,就是除自己外的左乘积或者右乘积(这里注意的是数组L[0]和数组R[0]计算的是
//nums 0-L-1的乘积
class Solution {
public int[] productExceptSelf(int[] nums) {
int length = nums.length;
int[] L = new int[length];
int[] R = new int[length];
int[] answer = new int[length];
// 初始化L数组,第一个元素左边没有元素,所以为1
L[0] = 1;
// 从左到右计算L数组
for (int i = 1; i < length; i++) {
L[i] = L[i - 1] * nums[i - 1];
}
// 初始化R数组,最后一个元素右边没有元素,所以为1
R[length - 1] = 1;
// 从右到左计算R数组
for (int i = length - 2; i >= 0; i--) {
R[i] = R[i + 1] * nums[i + 1];
}
// 计算答案数组
for (int i = 0; i < length; i++) { // 注意这里要迭代到length
answer[i] = L[i] * R[i];
}
return answer;
}
}