【力扣篇一】数组30道题汇总(2)

简介: 二维数组及滚动数组118. 杨辉三角 | 2022-12-7在考虑边界问题时脑袋常常容易混乱,又会犹豫是把边界情况单独处理,还是在形式上统一到普通情况中处理。

【力扣篇一】数组30道题汇总(1)https://developer.aliyun.com/article/1406750

二维数组及滚动数组

118. 杨辉三角 | 2022-12-7

在考虑边界问题时脑袋常常容易混乱,又会犹豫是把边界情况单独处理,还是在形式上统一到普通情况中处理。

//首次通过
//0ms,击败100%
class Solution {
public:
    vector<vector<int>> generate(int numRows) {
        vector<vector<int>> a(numRows);
        a[0].push_back(1);
        for(int i = 1; i < numRows; i++){
            int nSize = a[i - 1].size();  //前一层的长度
            for(int j = 0; j < i + 1; j++){
                int num = 0;
                if(j < nSize){
                    num += a[i - 1][j];
                }
                if(j - 1 >= 0){
                    num += a[i - 1][j - 1];
                }
                a[i].push_back(num);
            }
        }
        return a;
    }
};

119. 杨辉三角 II | 2022-12-7

要得到第 n 行,只需先逐行求出前 n 行,然后返回时只返回最后一行就可以了。但有没有一种方法直接求第 n 行呢?

//首次通过
//0ms,击败100%
class Solution {
public:
    vector<int> getRow(int rowIndex) {
        int numRows = rowIndex + 1;
        vector<vector<int>> a(numRows);
        a[0].push_back(1);
        for(int i = 1; i < numRows; i++){
            int nSize = a[i - 1].size();  //前一层的长度
            for(int j = 0; j < i + 1; j++){
                int num = 0;
                if(j < nSize){
                    num += a[i - 1][j];
                }
                if(j - 1 >= 0){
                    num += a[i - 1][j - 1];
                }
                a[i].push_back(num);
            }
        }
        return a[rowIndex];
    }
};

661. 图片平滑器 | 2022-12-7

多层循环嵌套遍历这我熟,嘿嘿。之前写过一个自动填数独的程序,可以看看,不回溯,试试候选数法1ms高效解数独谜题-C++实现。

//首次通过
//40ms,击败93.78%
class Solution {
public:
    vector<vector<int>> imageSmoother(vector<vector<int>>& img) {
        int iSize = img.size();
        int jSize = img[0].size();
        vector<vector<int>> img_2(iSize, vector<int>(jSize));
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                int sum = 0;
                int count = 0;
                for(int m = i - 1; m <= i + 1; m++){
                    for(int n = j - 1; n <= j + 1; n++){
                        if(m >= 0 && n >=0 && m < iSize && n < jSize){
                            sum += img[m][n];
                            count += 1;
                        }
                    }
                }
                img_2[i][j] = sum / count;
            }
        }
        return img_2;
    }
};

598. 范围求和 II | 2022-12-7

//首次通过
//12ms,击败44.68%
class Solution {
public:
    int maxCount(int m, int n, vector<vector<int>>& ops) {
        int minM = 4*1e4, minN = 4*1e4;
        int result = 0;
        if(ops.size() == 0){
            return m * n;
        }
        for(auto op : ops){
            if(minM > op[0]){
                minM = op[0];
            }
            if(minN > op[1]){
                minN = op[1];
            }
        }
        return minM * minN;
    }
};

419. 甲板上的战舰 | 2022-12-7  

题目的进阶要求是,只使用 O ( 1 )  额外空间,并且不修改 board 的值。下面的代码中修改 board 的值了。

//首次通过
//8ms,击败61.98%
class Solution {
public:
    int countBattleships(vector<vector<char>>& board) {
        int iSize = board.size();
        int jSize = board[0].size();
        int count = 0;
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                if(board[i][j] == 'X'){
                    count += 1;
                    for(int k = j + 1; k < jSize && board[i][k] == 'X'; k++){
                        board[i][k] = '.';
                    }
                    for(int k = i + 1; k < iSize && board[k][j] == 'X'; k++){
                        board[k][j] = '.';
                    }
                }
            }
        }
        return count;
    }
};

下面的代码是满足进阶要求的版本,遍历矩阵,以如下三种情况统计战舰数量:

1、单独的一个 X;

2、横向战舰左端点处的 X;

3、纵向战舰上端点处的 X。

using namespace std;
class Solution {
public:
    int countBattleships(vector<vector<char>>& board) {
        int iSize = board.size();
        int jSize = board[0].size();
        int count = 0;
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                if(board[i][j] == 'X'){
                    if((i-1 < 0 || board[i-1][j] == '.') && (i+1 < iSize && board[i+1][j] == 'X')){
                        count += 1;
                    }
                    else if((j-1 < 0 || board[i][j-1] == '.') && (j+1 < jSize && board[i][j+1] == 'X')){
                        count += 1;
                    }
                    else if((i-1 < 0 || board[i-1][j] == '.') && (i+1 >= iSize || board[i+1][j] == '.') && (j-1 < 0 || board[i][j-1] == '.') && (j+1 >= jSize || board[i][j+1] == '.')){
                        count += 1;
                    }
                }
            }
        }
        return count;
    }
};

数组的旋转

【精】189. 轮转数组 | 2022-12-7

冒泡的灵感,递归的思路,迭代的写法 (递归占用的栈空间应当也算程序的空间复杂度)。感觉这道题挺有意思,而且能自己写出来挺有成就感的,题解里好像没看到我一样的思路,不过他们的思路也很棒哈哈。我这还是相对复杂了一点。

简单介绍下思路吧。我们知道冒泡排序中,每次都是交换相邻的两个数字,而这里我们是不断地交换相邻的两个长为 k 的子数组。如下图所示,直到图中的最后 k kk 个数字[ 7 , 8 , 9 ] [7,8,9][7,8,9]冒到了最前面,我们就成功完成了轮转数组的任务。

12a6fffce5d74b7fb7384bf568ee651c.png

但是,当剩余的 l e n lenlen 小于 k kk 的时候怎么办呢?如下图,这时我们先交换一部分,然后更新 k = k − l e n k=k-lenk=k−len,将剩下的 [ 1 , 2 , 5 , 6 ] [1,2,5,6][1,2,5,6],再看作原任务的一个子任务,递归求解。

1cdd4a2aa3e7468a8eac583fc3f90b07.png

//修订
//24ms, 击败72.88%
using namespace std;
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        int nSize = nums.size();
        k = k % nSize;  //移动nSize次就又回来了
        if(k == 0) { return; }
        int f = 0;
        int left = nSize - k;
        //f, left, k这3个变量控制递归状态
        while(f < left){
            int len = left - f;
            int a(0), b(0), m(0);
            if(len >= k){
                a = left - k;
                b = left;
                m = k;
                left = left - k;
            }
            else{
                a = f;
                b = f + len;
                m = len;
                k = k - len;
                f = f + len;
                left = f + len;
            }
            for(int i = 0; i < m; i++, a++, b++){
                swap(nums[a], nums[b]);
            }
        }
        return;
    }
};

如果讨厌太多行的代码,可以勉强挤成下面这样,但我不会建议你这样做,因为这几乎不会提高代码的可读性

using namespace std;
class Solution {
public:
    void rotate(vector<int>& nums, int k) {
        k = k % nums.size();
        if(k == 0) { return; }
        int f = 0;
        int left = nums.size() - k;
        while(f < left){
            int len = left - f;
            int a = len >= k ? left - k : f;
            int b = len >= k ? left : f + len;
            int m = len >= k ? k : len;
            f = len >= k ? f : f + len;
            left = len >= k ? left - k : f + len;
            k = len >= k ? k : k - len;
            for(int i = 0; i < m; i++, a++, b++){
                swap(nums[a], nums[b]);
            }
        }
        return;
    }
};

396. 旋转函数 | 2022-12-7

关键在于想办法减少重复计算。

//首次通过,112ms,击败73.40%
class Solution {
public:
    int maxRotateFunction(vector<int>& nums) {
        int nSize = nums.size();
        vector<int> F;
        int f(0);
        for(int i = 0; i < nSize; i++){
            f += nums[i] * i;
        }
        F.push_back(f);
        int delta(0);
        for(int i = 0; i < nSize-1; i++){
            delta += nums[i];
        }
        delta -= nums[nSize-1] * (nSize-1);
        for(int i = nSize-1; i > 0; i--){
            f = f + delta;
            F.push_back(f);
            delta = delta + (nums[i] - nums[i-1]) * nSize;
        }
        int result = *max_element(F.begin(), F.end());
        return result;
    }
};

特定顺序遍历二维数组

54. 螺旋矩阵 | 2022-12-7

总想找到某种具有统一性的写法,以避免过多的分支结构。

//首次通过,0ms,击败100%
class Solution {
public:
    vector<int> spiralOrder(vector<vector<int>>& matrix) {
        vector<int> result;
        vector<int> deltaI = {0, 1, 0, -1};
        vector<int> deltaJ = {1, 0, -1, 0};
        int iSize = matrix.size();
        int jSize = matrix[0].size();
        int mSize = iSize * jSize;
        int null = 666;
        for(int count(0), state(0), i(0), j(0); count < mSize; count++, i += deltaI[state], j += deltaJ[state]){
            int iNext = i + deltaI[state];
            int jNext = j + deltaJ[state];
            if(iNext < 0 || iNext >= iSize || jNext < 0 || jNext >= jSize || matrix[iNext][jNext] == null){
                state = (state + 1) % 4;
            }
            result.push_back(matrix[i][j]);
            matrix[i][j] = null;
        }
        return result;
    }
};

59. 螺旋矩阵 II | 2022-12-8

只需在遍历螺旋矩阵的代码上稍作修改即可 。

//首次通过,0ms,击败100%
class Solution {
public:
    vector<vector<int>> generateMatrix(int n) {
        vector<vector<int>> result(n, vector<int>(n));
        vector<int> deltaI = {0, 1, 0, -1};
        vector<int> deltaJ = {1, 0, -1, 0};
        int mSize = n * n;
        int null = 0;
        for(int count(0), state(0), i(0), j(0); count < mSize; count++, i += deltaI[state], j += deltaJ[state]){
            int iNext = i + deltaI[state];
            int jNext = j + deltaJ[state];
            if(iNext < 0 || iNext >= n || jNext < 0 || jNext >= n || result[iNext][jNext] != null){
                state = (state + 1) % 4;
            }
            result[i][j] = count + 1;
        }
        return result;
    }
};

498. 对角线遍历 | 2022-12-8

  • 右上时,如果走不了(会出界)就改为向,还走不了就向
  • 左下时,如果走不了就改为向,还走不了就向
//首次通过,16ms,击败98.43%
class Solution {
public:
    vector<int> findDiagonalOrder(vector<vector<int>>& mat) {
        vector<int> result;
        vector<int> deltaI = {-1, 1};
        vector<int> deltaJ = {1, -1};
        int iSize = mat.size();
        int jSize = mat[0].size();
        int mSize = iSize * jSize;
        for(int count(0), arrow(0), i(0), j(0); count < mSize; count++){
            result.push_back(mat[i][j]);
            int iNext = i + deltaI[arrow];
            int jNext = j + deltaJ[arrow];
            if(iNext >= 0 && iNext < iSize && jNext >= 0 && jNext < jSize){
                i = iNext;
                j = jNext;
            }
            else{
                if((arrow == 0 && j+1 < jSize) || (arrow == 1 && i+1 >= iSize)) 
                    j += 1;
                else 
                    i += 1;
                arrow = (arrow + 1) % 2;
            }
        }
        return result;
    }
};

二维数组变换

566. 重塑矩阵 | 2022-12-8

同步遍历两个矩阵即可。

//首次通过,8ms,86.60%
class Solution {
public:
    vector<vector<int>> matrixReshape(vector<vector<int>>& mat, int r, int c) {
        int iSize = mat.size();
        int jSize = mat[0].size();
        int Size = iSize * jSize;
        if(r * c != Size)
            return mat;
        vector<vector<int>> result(r, vector<int>(c));
        for(int i(0), j(0), m(0), n(0), count(0); count < Size; count++){
            result[m][n] = mat[i][j];
            i += (j+1) / jSize;
            j = (j+1) % jSize;
            m += (n+1) / c;
            n = (n+1) % c;
        }
        return result;
    }
};

48. 旋转图像 | 2022-12-8

有一段时间没有体会这种糟糕的编码体验了,4层的for循环和复杂的边界条件控制给我造成了很多麻烦。

  • for循环1:控制矩阵的圈层,从外到里;
  • for循环2:遍历当前圈层的一条边;
  • for循环3:遍历当前边上一个点在四条边的对应点;
  • for循环4:顺时针找下一个对应点。

后面两层循环其实可以省去,改成同时遍历一圈的4条边。

看力扣题解中另一种方法也不错,通过两次翻转即可。一次关于对角线镜像翻转;一次关于轴对称翻转。

//首次通过,0ms,击败100%
class Solution {
public:
    void rotate(vector<vector<int>>& matrix) {
        int n = matrix.size();
        vector<int> deltaI = {0, 1, 0, -1};
        vector<int> deltaJ = {1, 0, -1, 0};
        for(int a(0), b(0), len(n); len > 0; a +=1, b += 1, len -= 2){
            for(int c(a), d(b); d < b + len - 1; d++){
                for(int i(c), j(d), t1(matrix[c][d]), count(0); count < 4; count++){
                    int iNext(i), jNext(j);
                    for(int k(0), state(count); k < len-1; k++){  //定位next
                        int iNNext = iNext + deltaI[state];
                        int jNNext = jNext + deltaJ[state];
                        if(iNNext < a || iNNext >= n-a || jNNext < a || jNNext >= n-a){
                            state = (state + 1) % 4;
                        }
                        iNext += deltaI[state];
                        jNext += deltaJ[state];
                    }
                    int t2 = matrix[iNext][jNext];
                    matrix[iNext][jNext] = t1;
                    t1 = t2;
                    i = iNext;
                    j = jNext;
                }
            }
        }
    }
};

73. 矩阵置零 | 2022-12-8

写完再看题目,发现下面代码使用的额外空间是 O(m+n),而不是题目要求的 O(1)。

//首次通过,12ms,击败75.50%
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int iSize = matrix.size();
        int jSize = matrix[0].size();
        vector<bool> r(iSize);
        vector<bool> c(jSize);
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                if(matrix[i][j] == 0){
                    r[i] = true;
                    c[j] = true;
                }
            }
        }
        cout << endl;
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                if(r[i] == true || c[j] == true){
                    matrix[i][j] = 0;
                }
            }
        }
    }
};

于是我重新得到了以下版本,

//20ms,击败8.60%
class Solution {
public:
    void setZeroes(vector<vector<int>>& matrix) {
        int iSize = matrix.size();
        int jSize = matrix[0].size();
        int a(0);
        int b(0);
        bool showZero(false);
        //找到一个0的位置,其所在行列被我们用来存放标记
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                if(matrix[i][j] == 0){
                    a = i;
                    b = j;
                    showZero = true;
                    break;
                }
            }
        }
        if(showZero == false){ return; }
        //将所在行和列不是0的元素标记为2,为后面排除原本存在的1的干扰
        for(int i = 0; i < iSize; i++){
            if(matrix[i][b] != 0){
                matrix[i][b] = 2;
            }
        }
        for(int j = 0; j < jSize; j++){
            if(matrix[a][j] != 0){
                matrix[a][j] = 2;
            }
        }
        //遍历矩阵,标记存在0的行和列
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                if(matrix[i][j] == 0){
                    matrix[i][b] = 1;
                    matrix[a][j] = 1;
                }
            }
        }
        //遍历矩阵,置零操作
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                if((i != a && j != b) && (matrix[i][b] == 1 || matrix[a][j] == 1)){
                    matrix[i][j] = 0;
                }
            }
        }
        //将我们存放标记的行列也置零
        for(int i = 0; i < iSize; i++){
            matrix[i][b] = 0;
        }
        for(int j = 0; j < jSize; j++){
            matrix[a][j] = 0;
        }
    }
};

思维方向是可以的,即“改造原矩阵的一部分,作为我们存放标记的空间”,但这段代码在时间效率和代码简洁度上仍有较大的优化空间。但是,就这样吧,它已经满足题目要求了,哈哈。

289. 生命游戏 | 2022-12-9

为了实现原地算法,我们可以给细胞引入两个额外的状态,即包含过程信息的状态。

//首次通过,0ms,击败100%
class Solution {
public:
    void gameOfLife(vector<vector<int>>& board) {
        const int oldDie = 2;  //初始状态是死细胞,下一个状态会复活
        const int oldLive = 3;  //初始状态是活细胞,下一个状态会死
        int iSize = board.size();
        int jSize = board[0].size();
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                int count = 0;
                for(int m = i-1; m <= i+1; m++){
                    for(int n = j-1; n <= j+1; n++){
                        if((m >= 0 && m < iSize && n >=0 && n <jSize) && (m != i || n != j) && (board[m][n] == 1 || board[m][n] == oldLive)){
                            count += 1;
                        }
                    }
                }
                if(board[i][j] == 1 && (count < 2 || count > 3)){
                    board[i][j] = oldLive;
                }
                else if(board[i][j] == 0 && count == 3){
                    board[i][j] = oldDie;
                }
            }
        }
        for(int i = 0; i < iSize; i++){
            for(int j = 0; j < jSize; j++){
                if(board[i][j] == oldDie){
                    board[i][j] = 1;
                }
                if(board[i][j] == oldLive){
                    board[i][j] = 0;
                }
            }
        }
    }
};

前缀和数组

303. 区域和检索 - 数组不可变 | 2022-12-9

//首次通过,260ms,击败13.75%
class NumArray {
public:
    vector<int> numS;
    NumArray(vector<int>& nums) {
        numS = nums;
    }
    int sumRange(int left, int right) {
        int sum(0);
        for(int i = left; i <= right; i++){
            sum += numS[i];
        }
        return sum;
    }
};

可我没想到,大家面对简单题也在重拳出击。下面是利用前缀和的解法,将单次查询中的时间复杂度优化到了 O(1)。

//优化,20ms,击败80.16%
class NumArray {
public:
    vector<int> sums;
    NumArray(vector<int>& nums) {
        int nSize = nums.size();
        sums.push_back(nums[0]);
        for(int i = 1; i < nSize; i++){
            sums.push_back(sums[i-1] + nums[i]);
        }
    }
    int sumRange(int left, int right) {
        int sum = 0;
        sum = sums[right] - (left > 0 ? sums[left - 1] : 0);
        return sum;
    }
};

304. 二维区域和检索 - 矩阵不可变 | 2022-12-9

从一维到二维的升级版,思路相似。这题因为对二维的vector不熟,卡了一会儿;此外就是折磨人的边界问题。

//首次通过,324ms,击败89.77%
class NumMatrix {
public:
    vector<vector<int>> sums;
    NumMatrix(vector<vector<int>>& matrix) {
        int iSize = matrix.size();
        int jSize = matrix[0].size();
        for(int i = 0; i < iSize; i++){
            sums.push_back(vector<int>(0));
            for(int j = 0; j < jSize; j++){
                int A = i > 0 ? sums[i-1][j] : 0;
                int B = j > 0 ? sums[i][j-1] : 0;
                int C = i > 0 && j > 0 ? sums[i-1][j-1] : 0;
                int sum = matrix[i][j] + A + B - C;
                sums[i].push_back(sum);
            }
        }
    }
    int sumRegion(int row1, int col1, int row2, int col2) {
        int all = sums[row2][col2];
        int A = row1 > 0 ? sums[row1-1][col2] : 0;
        int B = col1 > 0 ? sums[row2][col1-1] : 0;
        int C = row1 > 0 && col1 > 0 ? sums[row1-1][col1-1] : 0;
        int sum = all - A - B + C;
        return sum;
    }
};

238. 除自身以外数组的乘积 | 2022-12-9

别人怎么可以这么聪明?这题我没写出来,摸到了窗户纸,但就是没捅破。

一个基本是思路是,三次遍历数组,

  • 第一次正向遍历,计算从第一个数到当前位置的区间内,所有数字的乘积,放入一个数组 A;
  • 第二次反向遍历,计算从最后一个数到当前位置的区间内,所有数字的乘积,放入另一个数组 B;
  • 第三次随便遍历,answer[i] = A[i-1] * B[i+1]。

基于上述思路进行改进,我们可以用输出数组answer作为数组B,然后第三次遍历进行正向遍历,而A则可以随着遍历过程动态生成,得到了以下代码。

//首次通过,20ms,击败73.59%
class Solution {
public:
    vector<int> productExceptSelf(vector<int>& nums) {
        int nSize = nums.size();
        vector<int> out(nSize);
        out[nSize-1] = nums[nSize-1];
        for(int i = nSize-2; i >= 0; i--){
            out[i] = out[i+1] * nums[i];
        }
        for(int i = 0, product = 1; i < nSize; i++){
            int A = product;
            int B = i < nSize-1 ? out[i+1] : 1;
            out[i] = A * B;
            product *= nums[i];
        }
        return out;
    }
};

敬请期待下一节——字符串。


相关文章
|
4天前
|
算法
LeetCode第53题最大子数组和
LeetCode第53题"最大子数组和"的解题方法,利用动态规划思想,通过一次遍历数组,维护到当前元素为止的最大子数组和,有效避免了复杂度更高的暴力解法。
LeetCode第53题最大子数组和
|
6天前
|
存储 Java API
LeetCode------合并两个有序数组(4)【数组】
这篇文章介绍了LeetCode上的"合并两个有序数组"问题,并提供了三种解法:第一种是使用Java的Arrays.sort()方法直接对合并后的数组进行排序;第二种是使用辅助数组和双指针技术进行合并;第三种则是从后向前的双指针方法,避免了使用额外的辅助数组。
LeetCode------合并两个有序数组(4)【数组】
LeetCode------找到所有数组中消失的数字(6)【数组】
这篇文章介绍了LeetCode上的"找到所有数组中消失的数字"问题,提供了一种解法,通过两次遍历来找出所有未在数组中出现的数字:第一次遍历将数组中的每个数字对应位置的值增加数组长度,第二次遍历找出所有未被增加的数字,即缺失的数字。
|
6天前
|
前端开发
LeetCode------移动零(5)【数组】
这篇文章介绍了LeetCode上的"移动零"问题,提出了一种使用双指针的原地操作解法,该方法首先将非零元素移动到数组前端并保持相对顺序,然后填充后续位置为零,以达到题目要求。
|
4天前
|
算法
LeetCode第81题搜索旋转排序数组 II
文章讲解了LeetCode第81题"搜索旋转排序数组 II"的解法,通过二分查找算法并加入去重逻辑来解决在旋转且含有重复元素的数组中搜索特定值的问题。
LeetCode第81题搜索旋转排序数组 II
|
4天前
|
算法 索引
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
这篇文章介绍了LeetCode第34题"在排序数组中查找元素的第一个和最后一个位置"的解题方法,通过使用双指针法从数组两端向中间同时查找目标值,有效地找到了目标值的首次和最后一次出现的索引位置。
LeetCode第34题在排序数组中查找元素的第一个和最后一个位置
|
4天前
|
算法
LeetCode第33题搜索旋转排序数组
这篇文章介绍了LeetCode第33题"搜索旋转排序数组"的解题方法,通过使用二分查找法并根据数组的有序性质调整搜索范围,实现了时间复杂度为O(log n)的高效搜索算法。
LeetCode第33题搜索旋转排序数组
|
6天前
|
存储 索引
LeetCode------两数之和(3)【数组】
这篇文章介绍了LeetCode上的"两数之和"问题,提供了两种解法:一种是暴力求解法,通过双层循环遍历数组元素对查找两数之和为目标值的索引,时间复杂度为O(n^2);另一种是使用HashMap优化,通过存储元素值和索引,时间复杂度降低到O(n)。
LeetCode------两数之和(3)【数组】
|
12天前
|
算法 Java 索引
LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解
LeetCode初级算法题:寻找数组的中心索引+x的平方根+三个数的最大乘积+Leetcode 149:直线上最多的点数 Java详解
23 0
|
12天前
|
存储 算法 Java
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
LeetCode初级算法题:反转链表+统计N以内的素数+删除排序数组中的重复项Java详解
10 0