LeetCode算法题-Find All Anagrams in a String(Java实现)
这是悦乐书的第228次更新,第240篇原创
01 看题和准备
今天介绍的是LeetCode算法题中Easy级别的第95题(顺位题号是438)。给定一个字符串s和一个非空字符串p,找到s中p的字谜的所有起始索引。字符串仅由小写英文字母组成,字符串s和p的长度不会大于20,100。输出顺序无关紧要。例如:
输入:s:“cbaebabacd” p:“abc”
输出:[0,6]
说明:
起始索引等于0的子字符串是“cba”,它是“abc”的字谜。
起始索引等于6的子字符串是“bac”,它是“abc”的字谜。
输入:s:“abab”p:“ab”
输出:[0,1,2]
说明:
起始索引等于0的子字符串是“ab”,它是“ab”的字谜。
起始索引等于1的子字符串是“ba”,它是“ab”的字谜。
起始索引等于2的子字符串是“ab”,它是“ab”的字谜。
本次解题使用的开发工具是eclipse,jdk使用的版本是1.8,环境是win7 64位系统,使用Java语言编写和测试。
02 第一种解法
题目的意思是在s中寻找由p中字符任意组成的字符串的起始索引。我们可以先将p中的字符及其出现次数存入一个256大小的整型数组,然后使用循环,从s的第一位字符开始,如果从第1位到p的长度位的字符都能匹配,那么就将起始索引添加进list中。
第一,为了多次使用存有p字符及其出现次数的数组,我们使用Arrays.copyOf方法,每次复制出一个新数组来处理,不影响原数组中的值。
第二,如果当前字符作为起始无法匹配,那么就结束内层循环,进入s下一个字符继续开始。
第三,因为是连续判断p的长度位,所以外层循环的次数控制为s的长度减去p的长度,直接使用s的长度会报下标越界异常。
public List<Integer> findAnagrams(String s, String p) {
List<Integer> list = new ArrayList<Integer>();
if (s == null || s.length() == 0 || s.length() < p.length()) {
return list;
}
int[] arr = new int[256];
for (char ch : p.toCharArray()) {
arr[ch]++;
}
int len = p.length();
for (int i=0; i<=s.length()-len; i++) {
boolean isMatch = true;
int[] arr2 = Arrays.copyOf(arr, 256);
for (int j=i; j<i+len; j++) {
if (--arr2[s.charAt(j)] < 0) {
isMatch = false;
break;
}
}
if (isMatch) {
list.add(i);
}
}
return list;
}
03 第二种解法
对于第一种解法,我们可以再简化下,同样是使用256大小的整型数组,但是我们将s也添加进256大小的数组中去。
先从0开始,将p中的字符及其出现次数添加进pArr数组中,同时将s中的前p的长度个字符添加进sArr数组中,进行第一次的比较,如果两数组相同,那么就将索引0添加进list中。接着,开始循环处理s中剩下的字符。
从p的长度开始作为循环的起始索引,往sArr中添加当前字符出现的次数,同时将s中左边字符出现的次数进行移除,即往sArr中添加新数的同时,移除旧数,然后判断两数组是否相等,相等就将起始索引添加进list中。
在本解法中,判断两数组是否相同使用的是Arrays.equals方法。
public List<Integer> findAnagrams2(String s, String p) {
List<Integer> list = new ArrayList<Integer>();
if (s == null || s.length() == 0 || s.length() < p.length()) {
return list;
}
int[] pArr = new int[256];
int[] sArr = new int[256];
for(int i=0; i<p.length(); i++){
pArr[p.charAt(i)]++;
sArr[s.charAt(i)]++;
}
if (Arrays.equals(pArr, sArr)) {
list.add(0);
}
for (int j=p.length(); j<s.length(); j++) {
++sArr[s.charAt(j)];
--sArr[s.charAt(j-p.length())];
if (Arrays.equals(pArr, sArr)) {
list.add(j-p.length()+1);
}
}
return list;
}
04 第三种解法
使用双指针。先将p中的字符及其出现次数初始化进256大小的整型数组,然后定义三个变量,第一个指针从0开始,表示从左,第二个指针也从0开始,表示向右,第三个变量为count,初始值为p的长度。
每次进入循环时,都将右指针向前移动1个单位,如果当前s中的字符存在于数组中,count减1,如果count等于0,则表示已经找到了s中满足p长度的字符串,此时就将左指针添加进list中。如果右指针减去左指针的大小等于p的长度,说明已经判断完一个p长度的字符串了,就需要将左指针往前移动一个单位,并且左指针指向的字符存在于数组中,count加1,最后返回list。
public List<Integer> findAnagrams3(String s, String p) {
List<Integer> list = new ArrayList<Integer>();
if (s == null || s.length() == 0 || s.length() < p.length()) {
return list;
}
int[] arr = new int[256];
for (char ch : p.toCharArray()) {
arr[ch]++;
}
int left = 0, right = 0, count = p.length();
while (right < s.length()) {
if (arr[s.charAt(right++)]-- >= 1) {
count--;
}
if (count == 0) {
list.add(left);
}
if (right - left == p.length() && arr[s.charAt(left++)]++ >= 0) {
count++;
}
}
return list;
}
05 小结
算法专题目前已连续日更超过两个月,算法题文章95+篇,公众号对话框回复【数据结构与算法】、【算法】、【数据结构】中的任一关键词,获取系列文章合集。
以上就是全部内容,如果大家有什么好的解法思路、建议或者其他问题,可以下方留言交流,点赞、留言、转发就是对我最大的回报和支持!
LeetCode算法题-Find All Anagrams in a String(Java实现)的更多相关文章
- LeetCode算法题-Number of Lines To Write String(Java实现)
这是悦乐书的第319次更新,第340篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第188题(顺位题号是806).我们要将给定字符串S的字母从左到右写成行.每行最大宽度为 ...
- LeetCode算法题-Minimum Distance Between BST Nodes(Java实现-四种解法)
这是悦乐书的第314次更新,第335篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第183题(顺位题号是783).给定具有根节点值的二叉搜索树(BST),返回树中任何两个 ...
- LeetCode算法题-Binary Number with Alternating Bits(Java实现)
这是悦乐书的第292次更新,第310篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第160题(顺位题号是693).给定正整数,检查它是否具有交替位:即它的二进制数的任意两 ...
- LeetCode算法题-Trim a Binary Search Tree(Java实现)
这是悦乐书的第284次更新,第301篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第152题(顺位题号是669).给定二叉搜索树以及L和R的最低和最高边界,修剪树以使其所 ...
- LeetCode算法题-Maximum Product of Three Numbers(Java实现)
这是悦乐书的第275次更新,第291篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第143题(顺位题号是628).给定一个整数数组,从其中找出三个数,使得乘积最大.例如: ...
- LeetCode算法题-Maximum Depth of N-ary Tree(Java实现)
这是悦乐书的第261次更新,第274篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第128题(顺位题号是559).给定n-ary树,找到它的最大深度.最大深度是从根节点到 ...
- LeetCode算法题-Convert BST to Greater Tree(Java实现)
这是悦乐书的第255次更新,第268篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第122题(顺位题号是538).给定二进制搜索树(BST),将其转换为更大树,使原始BS ...
- LeetCode算法题-K-diff Pairs in an Array(Java实现)
这是悦乐书的第254次更新,第267篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第121题(顺位题号是532).给定一个整数数组和一个整数k,您需要找到数组中唯一的k- ...
- LeetCode算法题-Minimum Absolute Difference in BST(Java实现)
这是悦乐书的第253次更新,第266篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第120题(顺位题号是530).给定具有非负值的二叉搜索树,找到任意两个节点的值之间的最 ...
随机推荐
- openssl dhparam(密钥交换)
openssl系列文章:http://www.cnblogs.com/f-ck-need-u/p/7048359.html openssl dhparam用于生成和管理dh文件.dh(Diffie-H ...
- Docker网络的基本功能操作示例
一.Docker常用的四种网络模型 1.第一种:使用网络名称空间,但不设置任何网络设备 这种模型中只有lo接口,是一个封闭式的容器,不能与外界进行通信.设置网络模型需要使用 --network 选项来 ...
- Redis 初次见面
目录 Redis 特性 使用场景 初次使用 安装(Linux) 配置 启动 redis 的 3 种方法 使用 redis 客户端 关闭 redis 服务 Redis 版本说明 引用 1 Redis 特 ...
- [转]Virtualbox主机和虚拟机之间文件夹共享及双向拷贝(Windows<->Windows, Windows<->Linux)
本文转自:https://www.jb51.net/article/97271.htm 最近学习Virtualbox的一些知识,记录下,Virtualbox下如何实现主机和虚拟机之间文件夹共享及双向拷 ...
- 高德地图Javascript API设置域名白名单
在涉及到GPS地图相关应用的开发过程中,我们需要在高德开放平台注册相应的账号,并设置好相应应用来获取调用的Key值,该Key值直接放入到网站前端页面,针对任何人来说都可看到,因此我们防止他人盗用你的K ...
- 【转载】ASP.NET以Post方式抓取远程网页内容类似爬虫功能
使用HttpWebRequest等Http相关类,可以在应用程序中或者网站中模拟浏览器发送Post请求,在请求带入相应的Post参数值,而后请求回远程网页信息.实现这一功能也很简单,主要是依靠Http ...
- Java 学习笔记 判断一个数组是否有序
思路 升序:每次比较数组中的两个数的时候,最大的数一定是前一个 降序: 每次比较数组中的两个数的时候,最小的数一定是前一个 Flag1和flag2都是假的时候,返回flase,否则,返回flase 代 ...
- python基础学习(十)字符串
字符串的定义 字符串 就是 一串字符,是编程语言中表示文本的数据类型 在 Python 中可以使用 一对双引号 " 或者 一对单引号 ' 定义一个字符串 虽然可以使用 \" 或者 ...
- Hibernate入门(六)---------HQL语句
Query: 代表面向对象的一个Hibernate查询操作.在Hibernate中,通常使用session.createQuery()方法接收一个HQL语句,然后调用Query的 list()或uni ...
- 设计模式—装饰模式的C++实现
这是Bwar在2009年写的设计模式C++实现,代码均可编译可运行,一直存在自己的电脑里,曾经在团队技术分享中分享过,现搬到线上来. 1. 装饰模式简述 1.1 目的 动态地给一个对象添加一些额外的职 ...