一、数组与字符串
1、寻找数组的中心索引
请计算数组的 中心下标
数组 中心下标 是数组的一个下标,其左侧所有元素相加的和等于右侧所有元素相加的和。
如果中心下标位于数组最左端,那么左侧数之和视为 0 ,因为在下标的左侧不存在元素。这一点对于中心下标位于数组最右端同样适用。
如果数组有多个中心下标,应该返回 最靠近左边 的那一个。如果数组不存在中心下标,返回 -1 。
完整代码如下:(前缀和等于后缀和)
#include<iostream>
#include<vector>
#include<numeric>
using namespace std;
class Solution {
public:
int pivotindex(vector <int>& nums) {
if (nums.empty())
{
return -1;
}
int left_sum = 0, right_sum = accumulate(nums.begin(), nums.end(), 0); //累加求和
for (int i = 0; i < nums.size(); i++)
{
left_sum += nums[i];
if (i > 0)
{
right_sum -= nums[i-1];
}
if (left_sum == right_sum)
{
cout << i << endl;
return i;
}
}
return -1;
}
void define(vector <int> &b, vector <int>::iterator& Iter1)
{
int d;
cout << "请输入输入数字的个数:" << endl;
scanf_s("%d", &d);
cout << "请输入数字:" << endl;
for (int i = 0; i < d; i++) //容器的初始化
{
int a;
scanf_s("%d",&a);
b.push_back(a);
}
cout << "容器中的数字是:("; //容器中数字的遍历
for (Iter1 = b.begin(); Iter1 != b.end(); Iter1++)
{
cout << *Iter1 << " ";
}
cout << ")." << endl;
}
};
int main()
{
Solution a;
vector <int> c;
vector <int>::iterator it;
a.define(c,it);
cout << a.pivotindex(c) << endl;;
return 0;
}
运行结果如下:
2、搜索插入位置
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
请必须使用时间复杂度为 O(log n) 的算法。
代码如下:(遍历,二分法)
//遍历
class Solution
{
public:
int searchInsert(vector<int>& a, int target)
{
for (int i = 0; i < a.size(); i++)
{
if(target<=a[i])
{
return i;
}
}
return a.size();
}
};
//二分法
class Solution
{
public:
int searchInsert(vector<int>& a, int target)
{
int left = 0, right = (a.size() - 1);
while (left < right)
{
int mid = left + (right - left) / 2;
if (a[mid]==target)
{
return mid;
}
else if (a[mid]>target)
{
right = mid - 1;
}
else if (a[mid] <target)
{
left = mid + 1;;
}
} //搜索完后,left=right=mid
return a[left] < target ? left + 1 : left;
}
}
运行结果:
3、合并区间
以数组 intervals 表示若干个区间的集合,其中单个区间为 intervals[i] = [starti, endi] 。请你合并所有重叠的区间,并返回一个不重叠的区间数组,该数组需恰好覆盖输入中的所有区间。
完整代码如下:
#include<iostream>
#include<vector>
#include<algorithm> //sort函数头文件
using namespace std;
class Solution
{
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) //返回值是二维数组类型
{
int n = intervals.size();
if (n == 1)
return intervals;
sort(intervals.begin(), intervals.end()); //先变成有序数组
vector<vector<int>> vec;
vec.push_back(intervals[0]);
int j = 0;
for (int i = j + 1; i < n; i++) {//如果前一个数组的最后一个数大于后面数组的第一个数,即有交集
if (intervals[i][0] <= vec[j][1])
vec[j][1] = max(vec[j][1], intervals[i][1]);//前一个数组的最后一个数赋值为数组的最大值
else {
vec.push_back(intervals[i]); //正常赋值
j++;
}
}
return vec;
}
void print(vector<vector<int>>& cd) //下标法打印二维数组
{
for (int i = 0; i < cd.size(); i++) //容器的个数
{
for (int j = 0; j < cd[i].size(); j++) //每个容器中的值
{
cout << cd[i][j] <<" ";
}
cout << endl;
}
}
};
int main()
{
Solution ab;
vector<vector<int>> c = { //直接赋值
{1,3},{2,6},{8,10},{15,18}
};
vector<vector<int> > d;
d = ab.merge(c);
ab.print(d);
return 0;
}
运行结果:
4、旋转矩阵
给你一幅由 N × N 矩阵表示的图像,其中每个像素的大小为 4 字节。请你设计一种算法,将图像旋转 90 度。不占用额外内存空间能否做到?
题目分析:
对角旋转:(蓝色表示步骤)
代码如下:
class Solution
{
public:
vector<vector<int>> rorate(vector<vector<int>>& a)
{
int n;
n = a.size();
//对角旋转
for (int i = 0; i < n; i++)
{
for (int j = 0; j < i; j++) //具体看下图
{
swap(a[i][j], a[j][i]);
}
}
//镜面旋转
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n/2; j++)
{
swap(a[i][j], a[i][n - j - 1]);
}
}
/*for (int i = 0; i < n; i++) //reverse函数会将(begin,end)区间内的函数全部逆序
{
reverse(a[i].begin(), a[i].end()); //函数在<algorithm>头文件下
}*/
return a;
}
}
运行结果:
五、零矩阵
编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零。
代码如下:
六、对角线遍历
给定一个含有 M x N 个元素的矩阵(M 行,N 列),请以对角线遍历的顺序返回这个矩阵中的所有元素。
分析:
由于每条对角线的x+y(num)值相等
规律为:若num为偶数时,x=num; 若num为奇数时,y=num
当x值或y值越界时,让x=行数减一 ,y=列数减一
代码如下:
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
vector<int> ans;
if(matrix.empty())
return ans;
int row = matrix.size(), col = matrix[0].size(), c = 0, r = 0;
for(int i=0;i < row+col-1;i++) //对角线x+y值一定相同
{
if(i % 2) //对角线值为奇数时
{
c = (i<col) ? i : col-1; //和小于行数时(左上三角矩阵),i=col 否则i=col-1(不能超过边界)
r = i - c;
while(c >= 0 && r < row)
ans.push_back(matrix[r++][c--]);
}
else //对角线值为奇数时
{
r = (i<row) ? i : row-1;
c = i - r;
while(c < col && r >= 0)
ans.push_back(matrix[r--][c++]);
}
}
return ans;
}
};
运行结果:
class Solution {
public:
vector<int> findDiagonalOrder(vector<vector<int>>& matrix) {
vector<int> ans;
if(matrix.empty())
return ans;
int row = matrix.size(), col = matrix[0].size(), c = 0, r = 0;
for(int i=0;i < row+col-1;i++)
{
if(i % 2)
{
c = (i<col) ? i : col-1;
r = i - c;
while(c >= 0 && r < row)
ans.push_back(matrix[r++][c--]);
}
else
{
r = (i<row) ? i : row-1;
c = i - r;
while(c < col && r >= 0)
ans.push_back(matrix[r--][c++]);
}
}
return ans;
}
};