数组和字符串
数组入门
寻找数组的中心索引
(暴力解法(不能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 - i
和n - 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 =