1.力扣_jz66_构建乘积数组
/**
* 给定一个数组 A[0,1,…,n-1],请构建一个数组 B[0,1,…,n-1],其中B[i] 的值是数组 A 中除了下标 i 以外的元素的积
* 即B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。
**/
public class Num66_构建乘积数组 {
/*方法1:左右乘积列表*/
/**
* 当前元素的值=除当前元素以外的元素的乘积=当前元素左边元素的总乘积*当前元素右边元素的总乘积
* 构建两个新数组left[]+right[],left[i]存储索引元素左边元素的总乘积,right[i]存储当前元素左边元素的总乘积
* 对于left数组,left[0]=1,因为第一个元素左边没有元素。其他元素:left[i]=left[i-1]*a[i-1]
* 对于right数组,right[length-1]=1,因为最后一个元素右边没有元素。其他元素:right[i]=right[i+1]*a[i+1]
* B[i]存储除当前下标以外的元素的乘积=i下标左侧元素之积*i下标右侧元素之积=left[i]*right[i]
* @param a
* @return
*/
public int[] constructArr(int[] a) {
int len=a.length;
int left[]=new int[len];
int right[]=new int[len];
int B[]=new int[len];
if(a==null||a.length==0){
return B;
}
//left[i]
left[0]=1;
for (int i = 1; i < len; i++) {
left[i]=left[i-1]*a[i-1];
}
//right[i]
right[len-1]=1;
for (int i = len-2; i >= 0; i--) {
right[i]=right[i+1]*a[i+1];
}
//B[i]
for (int i = 0; i < len; i++) {
B[i]=left[i]*right[i];
}
return B;
}
/*方法2:让B[i]直接表示i左侧元素乘积,遍历完左侧后定义一个数动态表示右侧乘积r。上一个方法空间复杂度O(n),这个O(1)*/
/**
* 由于输出数组不算在空间复杂度内,那么我们可以将 L 或 R 数组用输出数组来计算。
* 先把输出数组当作 L 数组来计算,然后再动态构造 R 数组得到结果。让我们来看看基于这个思想的算法。
* 算法
* 初始化 answer 数组,对于给定索引 i,answer[i] 代表的是 i 左侧所有数字的乘积。
* 构造方式与之前相同,只是我们试图节省空间,先把 answer 作为方法一的 L 数组。
* 这种方法的唯一变化就是我们没有构造 R 数组。而是用一个遍历来跟踪右边元素的乘积。并更新数组 answer[i]=answer[i]*Ranswer[i]=answer[i]∗R。然后 RR 更新为 R=R*a[i]R=R∗a[i],其中变量 RR 表示的就是索引右侧数字的乘积。
*/
public int[] constructArr2(int[] a) {
//要创建的B数组直接先表示为求左侧元素乘积
int[] B=new int[a.length];
if (a==null||a.length==0){
return B;
}
// B[i] 表示索引 i 左侧所有元素的乘积
// 因为索引为 '0' 的元素左侧没有元素, 所以 B[0] = 1
B[0]=1;
for (int i = 1; i < B.length; i++) {
B[i]=B[i-1]*a[i-1];
}
// r 为右侧所有元素的乘积
// 刚开始右边没有元素,所以 r = 1
int r=1;
for (int i = B.length-1; i >= 0; i--) {
B[i]=B[i]*r;//i的左侧元素的积B[i]*右侧元素的乘积r
// r 需要包含右边所有的乘积,所以计算下一个结果时需要将当前值a[i]乘到 r 上
r*=a[i];
}
return B;
}
}
2.力扣_数值的整数次方
实现 pow(x, n) ,即计算 x 的 n 次幂函数(即,x^n)。不得使用库函数,同时不需要考虑大数问题
//方法1:递归
public double myPow(double x, int n) {
long N=n;
//x^n,n>=0时正常计算,n<=0时先N=-N,再在最后结果上求倒数即得到结果:eg:2^2=4;2^-2=1/(-(-2))^2=1/4
return N>=0?quickMul(x,N):1.0/quickMul(x,-N);
}
private double quickMul(double x, long N) {
if(N==0){
return 1;
}
double res=quickMul(x,N/2);
return N%2==0?res*res:res*res*x;
}
//方法2:迭代
public double myPow1(double x, int n) {
long N=n;
//x^n,n>=0时正常计算,n<=0时先N=-N,再在最后结果上求倒数即得到结果:eg:2^2=4;2^-2=1/(-(-2))^2=1/4
return N>=0?quickMul1(x,N):1.0/quickMul1(x,-N);
}
private double quickMul1(double x, long N) {
double res=1.0;
// 贡献的初始值为 x
double x_con=x;
// 在对 N 进行二进制拆分的同时计算答案
while (N>0){
if(N%2==1){
// 如果 N 二进制表示的最低位为 1,那么需要计入贡献
res*=x_con;
}
// 将贡献不断地平方
x_con*=x_con;
// 舍弃 N 二进制表示的最低位,这样我们每次只要判断最低位即可
N/=2;
}
return res;
}
3.力扣_打印1到最大的n位数
public class Num17_打印从1到最大的n位数 {
public int[] printNumbers(int n) {
int end=(int) Math.pow(10,n)-1;
int[] res=new int[end];
for (int i = 0; i < end; i++) {
res[i]=i+1;
}
return res;
}
}
大数打印解法:力扣
4.力扣_表示数值的字符串
class Solution {
public boolean isNumber(String s) {
if(s == null || s.length() == 0) return false; // s为空对象或 s长度为0(空字符串)时, 不能表示数值
boolean isNum = false, isDot = false, ise_or_E = false; // 标记是否遇到数位、小数点、‘e’或'E'
char[] str = s.trim().toCharArray(); // 删除字符串头尾的空格,转为字符数组,方便遍历判断每个字符
for(int i=0; i<str.length; i++) {
if(str[i] >= '0' && str[i] <= '9') isNum = true; // 判断当前字符是否为 0~9 的数位
else if(str[i] == '.') { // 遇到小数点
if(isDot || ise_or_E) return false; // 小数点之前可以没有整数,但是不能重复出现小数点、或出现‘e’、'E'
isDot = true; // 标记已经遇到小数点
}
else if(str[i] == 'e' || str[i] == 'E') { // 遇到‘e’或'E'
if(!isNum || ise_or_E) return false; // ‘e’或'E'前面必须有整数,且前面不能重复出现‘e’或'E'
ise_or_E = true; // 标记已经遇到‘e’或'E'
isNum = false; // 重置isNum,因为‘e’或'E'之后也必须接上整数,防止出现 123e或者123e+的非法情况
}
else if(str[i] == '-' ||str[i] == '+') {
if(i!=0 && str[i-1] != 'e' && str[i-1] != 'E') return false; // 正负号只可能出现在第一个位置,或者出现在‘e’或'E'的后面一个位置
}
else return false; // 其它情况均为不合法字符
}
return isNum;
}
}
5.力扣_顺时针打印矩阵
public static int[] spiralOrder(int[][] matrix) {
if (matrix == null || matrix.length == 0 || matrix[0].length == 0) {
return new int[0];
}
int rows = matrix.length, columns = matrix[0].length;
int[] order = new int[rows * columns];
int index = 0;
int left = 0, right = columns - 1, top = 0, bottom = rows - 1;
while (left <= right && top <= bottom) {
for (int column = left; column <= right; column++) {
order[index++] = matrix[top][column];
}
for (int row = top + 1; row <= bottom; row++) {
order[index++] = matrix[row][right];
}
if (left < right && top < bottom) {
for (int column = right - 1; column > left; column--) {
order[index++] = matrix[bottom][column];
}
for (int row = bottom; row > top; row--) {
order[index++] = matrix[row][left];
}
}
left++;
right--;
top++;
bottom--;
}
return order;
}