一道题

有一字符串由M个单词组成单词之间有空格隔开(只有空格,没有其他标点符号),有N个关键字,现在要在字符串中找出包含N个关键字(每个关键字至少出现一次,没有说要不要按什么顺序)的最短子串。函数原型:String extractSummary(String description, String[] keywords)

 

-----------------------------------------------------------------------------------


1.为了方便处理。先将单词转换成数字。
  转换方式: 将所以出现的单词按字符串顺序排序, 之后每一个字符串都可以用二分查找找到一个下标,该下标即为该字符串转换之后的数字。于是问题转换为,给定一个数组和一个集合。 找出该数组中一个最短的连续子序列,使得该子序列包含集合中的所有数字。

2. 针对数字的处理方法:
  设要查找的列表为数组 A 。 令设一数组B, 数组B[i]=(A[i]的下一个在A数组中的出现位置,倘若后面没有出现则记为-1)。
  设两个指针 i, j均指向 A数组最开始的位置。 让J逐步右移,直到前j个元素满足包含集合所以元素的条件为止,此时便得到第一个合法解: [I,J]。

  指针i开始扫描,直到 b[i] > j 或者b[j] == -1。 当b[i] > j时,说明下一个a[i]已经不再序列区间[i,j]范围内。 此时令j = b[i],然后继续扫描。 直到扫描结束, 可以保证任意时刻序列区间[i,j]都是合法的。 记录一个全局最优解就好了 。

得到数字结果以后,再根据结果转换为原字符串的子串就好了。

 

------------------------------------------------------------------------------------

先得到所有关键字的位置,之后求包含所有关键字的最短长度是个很经典的问题。
可以有nlog(k)的解法,n是所有位置的个数,k是关键字的个数

解法如下:
对于每个关键字,它所有的位置排序放置。
同时对每个关键字设置一个当前哨卡位置,初值都指向第0个元素,计算最短长度。
从中找出一个起始位置最小的关键字元素,其位置向后移动一个(因为只有移动它,最短长度才有可能减少),再得到当前的最短长度
重复上述过程,直到某个关键字无法继续后移。

下面的代码简化了一点,只考虑了起始位置。

 


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值