1.机器人的运动范围
是数位和,裸BFS,用pair<int,int>存下标
class Solution {
public:
int book[55][55];
int get_sum(pair<int,int>p)
{
int s=0,num1=p.first,num2=p.second;
while(num1)
{
s+=(num1%10);
num1/=10;
}
while(num2)
{
s+=(num2%10);
num2/=10;
}
return s;
}
int movingCount(int threshold, int rows, int cols)
{
memset(book,0,sizeof book);
queue<pair<int,int> >q;
if(!rows||!cols) return 0;
int dx[4]={-1,0,1,0},dy[4]={0,1,0,-1};
int res=0;
q.push({0,0});
while(!q.empty())
{
auto top=q.front();
q.pop();
if(book[top.first][top.second]||get_sum(top)>threshold) continue;
book[top.first][top.second]=1;
res++;
for(int i=0;i<4;i++)
{
int newx=top.first+dx[i],newy=top.second+dy[i];
if(newx>=0&&newx<rows&&newy>=0&&newy<cols)
q.push({newx,newy});
}
}
return res;
}
};
2.剪绳子
class Solution {
public:
int maxProductAfterCutting(int length) {
//dp[i]表示绳子长度为i的最大乘积i~[2,n]
//由于必须切一刀,假设切在j位置,左边长度为j,则右边长度为i-j,对于右边长度,可切可不切
//dp[i]=max( j*(i-j) ,j*dp[i-j] )
int dp[length+10];
memset(dp,0,sizeof dp);
for(int i=2;i<=length;i++)
{
for(int j=1;j<i;j++)
{
dp[i]=max(dp[i],max(j*(i-j),j*dp[i-j]));
}
}
return dp[length];
}
};
3.二进制中1的个数
采用unsigned int转化为无符号整数
class Solution {
public:
int NumberOf1(int _n) {
unsigned int n=_n;
int res=0;
while(n)
{
if(n&1)res++;
n>>=1;
}
return res;
}
};
4.快速幂
注意如果指数是负数的话,需要取倒数
class Solution {
public:
double Power(double x, int n) {
typedef long long ll;
bool is_min=n<0;
double res=1;
ll k=abs(ll(n));
while(k)
{
if(k&1)
res*=x;
x*=x;
k>>=1;
}
if(is_min) res=1/res;
return res;
}
};
5.在O(1)时间复杂度内删除链表结点
由于是单链表,因此我们无法找到它的前驱节点,我们可以换一种思路,将下一个节点的值复制到当前节点,然后将下一个节点删除即可。
时间复杂度为:O(1)
class Solution {
public:
void deleteNode(ListNode* node) {
auto p=node ->next;
node->val=p->val;
node->next=p->next;
delete p;
}
};
6.删除链表中的重复的节点
定义一个虚拟头节点(dummy),防止头节点被删除,然后往后扫描整个链表(p),每次扫描元素相同的一段,如果这段中的元素个数多于1个,则将整段元素直接删除。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* deleteDuplication(ListNode* head) {
auto dummy=new ListNode(-1);
dummy->next=head;
auto p=dummy;
while(p->next)
{
auto q=p->next;
while(q&&q->val==p->next->val) q=q->next;//q存在不要忘记掉
//间隔一个
if(p->next->next==q) p=p->next;
//删掉大于等于2的间隔
else
p->next=q;
}
return dummy->next;
}
};
7.正则表达式匹配
对于这一类两个字符串匹配问题,可以用二维动态规划来写
状态表示:dp[i][j]表示s[i....]和p[j.....]匹配
状态计算:
- 1.p[j]是正常字符,dp[i][j]=s[i]==p[j]&&dp[i+1][j+1]
- 2.p[j]是' . ' , dp[i][j]=dp[i+1][j+1]
- 3.p[j+1]是' * '(p[j]是b * 这样的形式)
第一种出现0次, dp[i][j]=dp[i][j+2] ( 跳两个格子 )
第二种出现>=1次, dp[i][j]=dp[i+1][j]
8.调整数组顺序使奇数位于偶数前面
类似于快排的思想,利用两个指针,其中第一个指针从前往后找,第二个指针从后往前找,第一个指针遇到的为偶数,第二个指针遇到的是奇数,且满足不相遇,就把这两个指针交换
class Solution {
public:
void reOrderArray(vector<int> &array) {
int l=0,r=array.size()-1;
while(l<r)
{
while(l<r&&array[l]%2==1)l++;
while(l<r&&array[r]%2==0)r--;
if(l<r)
swap(array[l],array[r]);
}
}
};
9.链表中倒数第k个节点
双指针
class Solution {
public:
ListNode* findKthToTail(ListNode* pListHead, int k) {
ListNode* fast=pListHead,*slow=pListHead;
while(k--&&fast)
fast=fast->next;
if(k>=0) return NULL;
else
{
while(fast)
{
fast=fast->next;
slow=slow->next;
}
}
return slow;
}
};
10.链表中环的入口地址
哈希表
class Solution {
public:
unordered_map<ListNode *,int>mp;
ListNode *entryNodeOfLoop(ListNode *head) {
for(auto i=head;i;i=i->next)
{
if(mp[i]!=0)
{
return i;
}
else
{
mp[i]=1;
}
}
return NULL;
}
};
网友评论