目录
109:旋转字符串
110:合并k个已排序的链表
111:滑雪
109:旋转字符串
题目链接:旋转字符串_牛客题霸_牛客网 (nowcoder.com)
题目:
题解:
class Solution {
public:
bool solve(string A, string B)
{
int n=A.size();
if(n!=B.size()) return false;
for(int i=0;i<n;i++)
{
int j=0;
if(A[i]==B[j])
{
int left=i,right=j;
while(A[left]==B[right])
{
left++;
left%=n;
right++;
if(right==n-1) return true;
}
}
}
return false;
}
};
110:合并k个已排序的链表
题目链接:合并k个已排序的链表_牛客题霸_牛客网 (nowcoder.com)
题目:
题解:
解法1:建小堆,将所有节点放进堆中,再从堆顶逐个取出组成链表。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
#include <queue>
class Solution {
public:
//template<class T>
class compare
{
public:
bool operator()(const ListNode* x, const ListNode* y)
{
return x->val > y->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists)
{
ListNode* newhead=new ListNode(0);
priority_queue<ListNode*, vector<ListNode*>, compare> heap;
for(int i=0;i<lists.size(); i++)
{
ListNode* cur=lists[i];
while(cur)
{
heap.push(cur);
cur=cur->next;
}
}
ListNode* cur=newhead;
while(!heap.empty())
{
cur->next=heap.top();
heap.pop();
cur=cur->next;
}
cur->next=nullptr;
return newhead->next;
}
};
解法2:使用
std::sort
对所有链表节点指针调用compare()进行排序。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
#include <queue>
class Solution {
public:
//template<class T>
class compare
{
public:
bool operator()(const ListNode* x, const ListNode* y)
{
return x->val > y->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists)
{
ListNode* newhead=new ListNode(0);
vector<ListNode*> list;
for(int i=0;i<lists.size(); i++)
{
ListNode* cur=lists[i];
while(cur)
{
list.push_back(cur);
cur=cur->next;
}
}
ListNode* cur=newhead;
sort(list.begin(), list.end(), compare());
for(int i=list.size()-1;i>=0;i--)
{
cur->next=list[i];
cur=cur->next;
}
cur->next=nullptr;
return newhead->next;
}
};
解法3:因为各个小链表是排好序的,可以先将各个链表头节点加入堆中,从堆顶中找小的插入新链表中再pop()后,将堆顶节点的下一节点重新插入堆。
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* ListNode(int x) : val(x), next(nullptr) {}
* };
*/
class Solution {
public:
//template<class T>
class compare
{
public:
bool operator()(const ListNode* x, const ListNode* y)
{
return x->val > y->val;
}
};
ListNode* mergeKLists(vector<ListNode*>& lists)
{
ListNode* newhead=new ListNode(0);
priority_queue<ListNode*, vector<ListNode*>, compare> heap;
for(auto head:lists)
{
if(head!=nullptr)
{
heap.push(head);
}
}
ListNode* cur=newhead;
while(heap.size())
{
ListNode* t=heap.top();
heap.pop();
cur->next=t;
cur=cur->next;
if(t->next!=nullptr)
{
heap.push(t->next);
}
}
cur->next=nullptr;
return newhead->next;
}
};
解法4:利用归并排序思想,将链表一层一层向下划分直到为单个链表,再向上合并同时排序链表节点。
class Solution {
public:
//两个有序链表合并函数
ListNode* Merge2(ListNode* pHead1, ListNode* pHead2) {
//一个已经为空了,直接返回另一个
if (pHead1 == NULL)
return pHead2;
if (pHead2 == NULL)
return pHead1;
//加一个表头
ListNode* head = new ListNode(0);
ListNode* cur = head;
//两个链表都要不为空
while (pHead1 && pHead2) {
//取较小值的节点
if (pHead1->val <= pHead2->val) {
cur->next = pHead1;
//只移动取值的指针
pHead1 = pHead1->next;
} else {
cur->next = pHead2;
//只移动取值的指针
pHead2 = pHead2->next;
}
//指针后移
cur = cur->next;
}
//哪个链表还有剩,直接连在后面
if (pHead1)
cur->next = pHead1;
else
cur->next = pHead2;
//返回值去掉表头
return head->next;
}
//划分合并区间函数
ListNode* divideMerge(vector<ListNode*>& lists, int left, int right) {
if (left > right)
return NULL;
//中间一个的情况
else if (left == right)
return lists[left];
//从中间分成两段,再将合并好的两段合并
int mid = (left + right) / 2;
return Merge2(divideMerge(lists, left, mid), divideMerge(lists, mid + 1,
right));
}
ListNode* mergeKLists(vector<ListNode*>& lists) {
//k个链表归并排序
return divideMerge(lists, 0, lists.size() - 1);
}
};
111:滑雪
题目链接:滑雪_牛客题霸_牛客网 (nowcoder.com)
题目:
题解:
dfs+记忆化搜索
#include <iostream>
using namespace std;
const int N=110;
int m=0,n=0;
int board[N][N]={0};
int vis[N][N]={0};
int dx[4]={0,0,-1,1};
int dy[4]={-1,1,0,0};
int dfs(int i, int j)
{
if(vis[i][j]) return vis[i][j];
int len=1;
for(int k=0;k<4;k++)
{
int x=i+dx[k], y=j+dy[k];
if(x>=0 && y>=0 && x<n && y<m && board[x][y] > board[i][j])
{
len=max(len, 1+dfs(x, y));
}
}
vis[i][j]=len;
return len;
}
int main()
{
cin>>n>>m;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
cin>>board[i][j];
}
}
int ret=0;
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
ret=max(ret, dfs(i,j));
}
}
cout<<ret<<endl;
return 0;
}