LeetBook数组和字符串专题题解

数组和字符串

文章目录

数组入门

寻找数组的中心索引

(暴力解法(不能AC))
class Solution {
   
public:
    int pivotIndex(vector<int>& nums) {
   
        int size = nums.size();
        // 遍历中心点
        for (int center = 0; center < size; center ++)
        {
   
            int left = 0;
            int right = 0;
            // 算出中心点左边的总和
            for (int l = 0; l < center; l ++)
                left += nums[l];
            // 算出中心点右边的总和
            for (int r = center + 1; r < size; r ++)
                right += nums[r];
            // 判断左边的总和和右边的总和是否相等
            if (left == right)
                return center;
        }
        // 不存在就返回-1
        return -1;
    }
};
(前缀和)
class Solution {
   
public:
    int pivotIndex(vector<int>& nums) {
   
        int size = nums.size();
        // 求出从左到右的前缀和
        vector<int> left(size, 0);
        vector<int> right(size, 0);
        // 初始化第一个数
        left[0] = nums[0];
        right[size - 1] = nums[size - 1];
        // 处理左边的前缀和
        for (int i = 1; i < size; i ++)
            left[i] = nums[i] + left[i - 1];
        // 处理右边的前缀和
        for (int i = size - 2; i >= 0; i --)
            right[i] = nums[i] + right[i + 1];
        // 枚举中心点
        for (int center = 0; center < size; center ++)
        {
   
            int l = center == 0 ? 0 : left[center - 1];
            int r = center == size - 1 ? 0 : right[center + 1];
            if (l == r)
                return center;
        }
        return -1;
    }
};
(左右和)
class Solution {
   
public:
    int pivotIndex(vector<int>& nums) {
   
        if (nums.empty())
            return -1;
        int rightSum = 0, leftSum = 0;;
        for (int num : nums)
            rightSum += num;
        int size = nums.size();
        for (int i = 0; i < size; i ++)
        {
   
            // 左边数的总和
            leftSum += nums[i];
            // 右边数的总和
            if (i > 0)
                rightSum -= nums[i - 1];
            // 如果左边的总和和右边的总和相等就返回下标
            if (rightSum == leftSum)
                return i;
        }
        return -1;
    }
};
(前缀和不用数组)
class Solution {
   
public:
    int pivotIndex(vector<int>& nums) {
   
        int sum = 0;
        for (auto num : nums)
            sum += num;
        // 记录前缀和
        int preSum = 0;
        for (int i = 0; i < nums.size(); i ++)
        {
      
            // 右边数组中的和
            int rightSum = sum - preSum - nums[i];
            if (preSum == rightSum)
                return i;
            preSum += nums[i];
        }
        return -1;
    }
};

搜索插入位置

(二分)

(判断括号里的东西)

class Solution {
   
public:
    int searchInsert(vector<int>& nums, int target) {
   
        int l = 0, r = nums.size();
        while (l < r) 
        {
   
            int mid = l + r >> 1;
            if (nums[mid] >= target)
                r = mid;
            else 
                l = mid + 1;
        }
        return l;
    }
};
合并区间
class Solution {
   
public:
    typedef pair<int, int> PII;
    vector<vector<int>> merge(vector<vector<int>>& intervals) {
   
        vector<vector<int>> ans;
        int n = intervals.size(), m = intervals[0].size();
        PII seg[n];
        for (int i = 0; i < n; i ++)
        {
   
            int l = intervals[i][0], r = intervals[i][1];
            seg[i] = {
   l, r};
        }
        sort(seg, seg + n);// 将区间按左端点排序
        int left = seg[0].first, right = seg[0].second;
        for (int i = 1; i < n; i ++) 
        {
   
            int curL = seg[i].first, curR = seg[i].second;
            if (curL <= right)
                right = max(curR, right);
            else 
            {
   
                ans.push_back(vector<int>({
   left, right}));// 将一个区间放入答案中
                left = curL;
                right = curR;
            }    
        }
        ans.push_back({
   left, right});
        return ans;
    }
};

二维数组

》数组中数据的操作

*旋转矩阵

学到了二维矩阵的对称方式:

1)正对角线的对称反转

for (int i = 0; i < n; i ++)
{
   
    for (int j = 0; j <= i; j ++)
    {
   
        int tmp = matrix[i][j];
        matrix[i][j] = matrix[j][i];;
        matrix[j][i] = tmp;
    }
}

2)负对角线的对称反转

for (int i = 0; i < n; i ++)
{
   
    for (int j = 0; j < n - i; j ++)
    {
   
        int tmp = matrix[i][j];
        matrix[i][j] = matrix[n - 1 - j][n - 1 - i];;
        matrix[n - 1 - j][n - 1 - i] = tmp;
    }
}

3)上下对称

for (int i = 0; i < n / 2; i ++)
{
   
    for (int j = 0; j < n; j ++)
    {
   
        int tmp = matrix[i][j];
        matrix[i][j] = matrix[n - 1 - i][j];
        matrix[n - 1 - i][j] = tmp;
    }
}

因为二维矩阵的元素是一维矩阵,所以在上下对称的时候可以用整行整行换

for (int i = 0; i < n / 2; i ++)
    swap(matrix[i], matrix[n - 1 - i]);

4)左右对称

for (int i = 0; i < n; i ++)
{
   
    for (int j = 0; j < n / 2; j ++)
    {
   
        int tmp = matrix[i][j];
        matrix[i][j] = matrix[i][n - 1 - j];
        matrix[i][n - 1 - j] = tmp;
    }
}
(对称旋转法1)

思路:先负对角线对称再上下对称

class Solution {
   
public:
    void rotate(vector<vector<int>>& matrix) {
   
        int n = matrix.size();
        // 顺时针旋转270度
        // 负对角线对称
        for (int i = 0; i < n; i ++)
        {
   
            for (int j = 0; j < n - i; j ++)
            {
   
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[n - 1 - j][n - 1 - i];;
                matrix[n - 1 - j][n - 1 - i] = tmp;
            }
        }
        // 顺时针旋转180度
        for (int i = 0; i < n / 2; i ++)
        {
   
            for (int j = 0; j < n; j ++)
            {
   
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[n - 1 - i][j];
                matrix[n - 1 - i][j] = tmp;
            }
        }
    }
};

这个方法比较好理解一些,通过正对角线的对称,先逆时针旋转90度,然后在根据中间的对称轴对称。就是顺时针旋转90度主要要理解n - 1 - in - 1- j

思路:先正对角线对称再左右对称

(对称旋转法2)
class Solution {
   
public:
    void rotate(vector<vector<int>>& matrix) {
   
        int n = matrix.size();
        // 正对角线对称
        // 逆时针旋转90度
        for (int i = 0; i < n; i ++)
        {
   
            for (int j = 0; j <= i; j ++)
            {
   
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[j][i];;
                matrix[j][i] = tmp;
            }
        }
        // 顺时针旋转180度
        for (int i = 0; i < n; i ++)
        {
   
            for (int j = 0; j < n / 2; j ++)
            {
   
                int tmp = matrix[i][j];
                matrix[i][j] = matrix[i][n - 1 - j];
                matrix[i][n - 1 - j] = tmp;
            }
        }
    }
};

(旋转对称法3)

思路:先上下对称再正对角线对称

class Solution {
   
public:
    void rotate(vector<vector<int>>& matrix) {
   
        int n = matrix.size();
        for (int i = 0; i < n / 2; i ++)
            swap(matrix[i], matrix[n - 1 - i]);
        for (int i = 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hyzhang_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值