代码随想录 一星期总结 4.8-4.15

代码随想录 一星期总结 4.8-4.15

上星期的KMP

上星期说到:
字符串优化思想 是 当你匹配失败时 能不能利用前面已经匹配过的字符串的信息
那么KMP给出的答案是next数组
实际上 KMP只是一种比较经典的字符串匹配算法 而且大多数应用也并没有采用这种算法,大多数应用可能采用了其他算法 比如 BM算法 Sunday算法 这些算法比KMP快而且还好理解

next数组就是一种实现 next[i] 表示 s[0…i]的最长相等前后缀的前缀的下标
现在对一个模式串求出了他的next数组
在已经有next数组的情况下 如何进行对字符进行一个匹配呢?
首先假设一个情况
文本串 “aaaabbbccabacb”
模式串 “abc” 直接开始匹配!!!

int i=0,j=-1; #j代表已经匹配的下标
for(int i=0;i<s.size();i++)
	#如果不匹配 那么就得去调整j 使得 在移动的尽量少的情况下,s[i]=p[j+1] 
	while(j!=-1 && p[j+1]!=s[i])
	{
		j=next[j];
	}
	#匹配了  	
	if(p[j+1]==s[i])
	{
		j++;
	}
	if(j==p.size()-1) return true;
}
return false;

主要记住
1:j代表 已经匹配过的字符下标 因此初始化为 -1
2:通过判断 j+1是否与 s[i]匹配
如果 不匹配 则变换 j=next[j] 去找到可以移动幅度最小的下标j 同时满足 p[j+1] ==s[i]
经过一个while循环后 可能有两个条件 一个是找到了 一个是没找到了
如果找到了 那么匹配数+1 j++
如果没找到 通过 for 循环 使得 i++ j 不动

栈专题

学一学 queue 以及 stack 的一些语法
比如 queue 是可以 back的 但是 stack 是不可以back的
写到了逆波兰表达式这里
其实用逆波兰表达式求值就简单的入栈出栈就行
但是把中缀表达式变成逆波兰表达式才是重点 我感觉 求值(表达式值)

其他题目

这周 看到了一个面试题 就是把糖果平分给大家 然后问被分到的最低的那个人的糖果数
我当时想用贪心思路 没想出来
因为一直觉得二分跟那种序列的数组类型挂钩 不给我数组真没想到那个方面
看了题解发现二分搜索方案直接搜索 我感觉很叼
复习一下

		while(i<j)
		{
			int mid= i+j>>1;  #这是求右半边的左边点
			if ( check(mid) )
				{
					j=mid;
				} 
			else i=mid+1;
		}

还看了一题 是 leetcode 周赛的 利用前缀数组 求跟他相同数值的下标的绝对值之和
比如
[1,1,3,1,1,2,3] 对应的数组 就是[1+3+4,1+2+3,4,3+2+1,4+3+1,0,4]
我一开始怎么都想不出来 这怎么用o(1)的方法去求啊
后面发现是
噢 跟之前使用前缀和的题目确实是一样的 之前使用的是序列的值
这次我们使用的是 坐标的值 都是值 都是绝对值 一样的而且这还已经排序的了
比如 所以我们直接先对相同的坐标的vector 进行前缀和
之后 我们使用

右边=(sum[n]- sum[i]) - (n-i) * num[i]     #注意 这里的 num[i] 对应与 原数组的坐标 
左边=(sum[i] - num[i] * i) * (-1)
```这里 -1 是因为 小的-大的是 负数要乘上 -1 这样就代表i左边的绝对值之和
所以合并一下 左边+右边 就是对于坐标i来说他的等值距离之和了 这就是o(1)求法
当然还有一个方法 先求出第一个利用增量公式推出第二个 也是可以O(1)的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值