目录
56.合并区间
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
int N=intervals.size();
vector<vector<int>> res;
sort(intervals.begin(),intervals.end());//先按前端点排序,套路
int l=intervals[0][0],r=intervals[0][1];
vector<int> temp;//装每一个子区间的数组
int i;
temp.push_back(l);
for(i=0;i<N;i++){
if(intervals[i][0]<=r){//只要比之前有边界小都可并进来并更新右边界
r=max(r,intervals[i][1]);
}else{
temp.push_back(r);//把之前收集的最大右边界装好
res.push_back(temp);//
l=intervals[i][0];//重新以遍历到的区间为起点
r=intervals[i][1];
temp=vector<int>();
temp.push_back(l);
}
}
if(i==N){//结束加上结尾
temp.push_back(r);
res.push_back(temp);
}
return res;
}
};
61.旋转链表
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* rotateRight(ListNode* head, int k) {
ListNode* t0=head;
if(head==NULL) return NULL;
ListNode* r;
int n=0;
for(auto i=head;i!=NULL;i=i->next){
n++;//算共有几个节点
if(i!=NULL&&i->next==NULL) r=i;//顺便找到旋转前的尾节点
}
int k0=k%n;//旋转几个点
int cnt=0;
ListNode* i;
for(i=head;cnt+1!=n-k0;i=i->next){
cnt++;//主要是找到旋转后的尾节点
}
r->next=head;//屁股连头
ListNode* res=i->next;//旋转后的头
i->next=NULL;//旋转后的尾断尾
return res;
}
};
AC.1451单链表快速排序
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* getTail(ListNode* head) {
while(head->next){
head=head->next;
}
return head;
}
ListNode* quickSortList(ListNode* head) {
if(!head||head->next==NULL) return head;
auto left=new ListNode(-1),mid=new ListNode(-1),right=new ListNode(-1);//哨兵节点
auto ltail=left,mtail=mid,rtail=right;//虚拟尾节点
int val=head->val;
for(auto i=head;i!=NULL;i=i->next){//以头节点val为标准进行划分,由此可生成三条链表
if(i->val<val){
ltail->next=i;
ltail=ltail->next;
}
else if(i->val==val){
mtail->next=i;
mtail=mtail->next;
}else{
rtail->next=i;
rtail=rtail->next;
}
}
ltail->next=mtail->next=rtail->next=NULL;//结束符
left->next=quickSortList(left->next);//左边的链表排序
right->next=quickSortList(right->next);//右边的连接排序
getTail(left)->next=mid->next;//左边对接中间
getTail(left)->next=right->next;//中间对接右边,因为left和mid合成一段了,又因为mid可能为空所以用left表示中间段
return left->next;//返回真正头节点
}
};
AC.756蛇形矩阵
#include<iostream>
using namespace std;
const int N = 110;
int n, m;
int q[N][N];
int main() {
scanf("%d%d", &n, &m);
int dx[4] = { 0,1,0,-1 }, dy[4] = { 1,0,-1,0 };
int x = 0, y = 0,d=0;
for (int i = 1; i <= n*m; i++) {
q[x][y] = i;
int a = x + dx[d], b = y + dy[d];
if (a < 0 || a >= n || b < 0 || b >= m || q[a][b]) {//||是只要有一个条件满足就重新寻找方向
d = (d + 1) % 4;
a = x + dx[d], b = y + dy[d];
}
x = a, y=b;将找到的方向赋给x,y
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
printf("%d ", q[i][j]);
}
puts("");
}
}
73.矩阵置零
class Solution {
public:
void setZeroes(vector<vector<int>>& matrix) {
int N=matrix.size();
int M=matrix[0].size();
int st1=0,st2=0;//用于判断第0行和第0列是否需要设0
for(int i=0;i<N;i++){
if(matrix[i][0]==0){
st1=1;
break;
}
}
for(int i=0;i<M;i++){
if(matrix[0][i]==0){
st2=1;
break;
}
}
for(int i=1;i<N;i++){
for(int j=1;j<M;j++){//从[1][1]开始找一旦有0则记录在对应行
//和对应列的头部也就是第0行和第0列
if(matrix[i][j]==0){
matrix[i][0]=0;
matrix[0][j]=0;
}
}
}
for(int i=1;i<N;i++){
if(matrix[i][0]==0){
for(int j=0;j<M;j++){
matrix[i][j]=0;
}
}
}
for(int i=1;i<M;i++){
if(matrix[0][i]==0){
for(int j=0;j<N;j++){
matrix[j][i]=0;//i是列噢
}
}
}
if(st1){//最后才处理第0行和第0列,因为前面拿来装东西了,脏了,所以留最后更新
for(int i=0;i<N;i++){
matrix[i][0]=0;
}
}
if(st2){
for(int i=0;i<M;i++){
matrix[0][i]=0;
}
}
}
};
AC.1452寻找矩阵的极小值
// Forward declaration of queryAPI.
// int query(int x, int y);
// return int means matrix[x][y].
class Solution {
public:
vector<int> getMinimumValue(int n) {
typedef long long LL;//因为是比小,有可能爆int
int l=0,r=n-1,mid;
while(l<r){//二分按列进行划分查找,直到找到最后一列
mid=(l+r)>>1;
LL val=INT_MAX,res;
for(int i=0;i<n;i++){//在当前列上找到最小值
LL val1=query(i,mid);
if(val1<val){
val=val1;
res=i;
}
}
int n1=query(res,mid-1);//减少api调用次数
int n2=query(res,mid+1);
if((mid>0&&n1>val&&mid<n&&n2>val)||
(mid==0&&mid<n&&n2>val)||(mid>0&&n1>val&&mid==n-1)){
return {res,mid};//在左边界和右边界和中间值的极小值情况
}else if(n2<val){
l=mid+1;//肯定在mid列的右边列区域
}else{
r=mid-1;//左边区域查找
}
}
LL val=INT_MAX,res;
for(int i=0;i<n;i++){//最后一列上进行查找返回极值
LL val1=query(i,r);
if(val1<val){
val=val1;
res=i;
}
}
return {res,r};
}
};
74.搜索二维矩阵
class Solution {
public:
bool searchMatrix(vector<vector<int>>& matrix, int target) {
int m=matrix.size(),n=matrix[0].size();
int l=0,r=m-1;//先在行头二分查找
while(l<r){
int mid=(l+r)/2;
if(matrix[mid][0]<target){
l=mid+1;
}else{
r=mid;//结果会是第一个大于等于目标值的行头
}
}
if(matrix[r][0]==target) return true;
else if(matrix[r][0]<target){//行头小过目标值说明在当前行
int l1=0,r1=n-1;
while(l1<r1){
int mid=(l1+r1)/2;
if(matrix[r][mid]<target){
l1=mid+1;
}else{
r1=mid;
}
}
if(matrix[r][r1]==target) return true;
else return false;
}
else{//行头大过目标值说明在上一行
if(r==0) return false;//特殊情况
int l1=0,r1=n-1;
while(l1<r1){
int mid=(l1+r1)/2;
if(matrix[r-1][mid]<target){
l1=mid+1;
}else{
r1=mid;
}
}
if(matrix[r-1][r1]==target) return true;
else return false;
}
}
};
75.颜色分类
class Solution {
public:
void sortColors(vector<int>& nums) {//双指针
int N=nums.size();
int cnt0=0,cnt2=N-1;
for(int i=0;i<N;i++){
if(nums[i]==0&&i<cnt0){//如果是之前换过来的0就不用判断了
}else if(i>cnt2){//判断到了2也不用判断了
break;
}
else if(nums[i]==0){//只用排0和2,剩下就是1的位置了
swap(nums[i],nums[cnt0]);
cnt0++;
if(nums[i]!=1) i--;//如果换过来的不是1还得回退重新判断
}else if(nums[i]==2){
swap(nums[i],nums[cnt2]);
cnt2--;
if(nums[i]!=1) i--;
}
}
}
};
79.单词搜索
class Solution {
public:
int st[7][7];//避免回走
int res=0;//结果
int N,M,L;
bool exist(vector<vector<char>>& board, string word) {
memset(st,0,sizeof 0);
N=board.size(),M=board[0].size(),L=word.size();
for(int i=0;i<N;i++){
for(int j=0;j<M;j++){
if(board[i][j]==word[0]){//起点对了就开始dfs
dfs(board,i,j,word,0);
if(res==1) return true;
}
}
}
return res==1;
}
void dfs(vector<vector<char>>& board,int x,int y,string& word
,int idx){
if(x<0||y<0||x>=N||y>=M||st[x][y]||word[idx]!=board[x][y]) return;//越界或者回走或者不符
else{
if(idx==word.size()-1){//找到,结束
res=1;
st[x][y]=1;
return;
}
st[x][y]=1;
}
dfs(board,x,y-1,word,idx+1);//四个方向走一下看看
dfs(board,x-1,y,word,idx+1);
dfs(board,x+1,y,word,idx+1);
dfs(board,x,y+1,word,idx+1);
st[x][y]=0;//恢复现场
}
};
80.删除有序数组中的重复项Ⅱ
class Solution {
public:
int removeDuplicates(vector<int>& nums) {
int N=nums.size();
int idx=1;//结果集是下标,原地装,因为结果集元素数必定比原来少或相等
int cnt=1;//当前数字有几个了
if(N<=2) return N;
for(int i=1;i<N;i++){
if(nums[i]!=nums[idx-1])//和前面不同就清0
cnt=0;
if(cnt<2){//装进结果集
nums[idx++]=nums[i];
cnt++;
}
}
return idx;
}
};
81.搜索旋转排序数组Ⅱ
class Solution {
public:
bool search(vector<int>& nums, int target) {
int n = nums.size();
if (!n) {
return false;
}
if (n == 1) {
return nums[0] == target;
}
int l = 0, r = n - 1;
while (l <= r) {
int mid = (l + r+1) / 2;
if (nums[mid] == target) return true;
if(nums[mid]==nums[l]&&nums[mid]==nums[r]){//三都相同无法判断哪边有序,
//且这仨必定不是目标值,所以一步步减少区间
l++,r--;
}else if (nums[l] <= nums[mid]) {//左边有序
if (nums[l] <= target && target <= nums[mid]) {//目标值在左
r = mid - 1;
} else {//在右
l = mid;
}
} else {//右
if (nums[mid] <= target && target <= nums[r]) {
l = mid;
} else {
r = mid - 1;
}
}
}
return false;
}
};
82.删除排序链表中的重复元素Ⅱ
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplicates(ListNode* head) {
ListNode* pre=new ListNode(-1);//哨兵节点,其与now之间隔了一个节点哈
if(head==NULL) return NULL;
ListNode* now=head->next;
pre->next=head;
while(now!=NULL){
if(now->val==pre->next->val){//now的值和前面相邻的值相同
do{
now=now->next;
}while(now!=NULL&&now->val==pre->next->val);//找到不同的为止
if(pre->next==head) head=now;//头节点被删的话要改head
pre->next=now;//删重复的节点
if(now) now=now->next;//now往下走,要和pre之间隔一个格子的距离哈
}else{
pre=pre->next;
now=now->next;
}
}
return head;
}
};