我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复【资料】,即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板。
题目
实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
示例1:
- 输入: s = "leetcode"
- 输出:false
示例2:
- 输入:s = "abc"
- 输出:true
限制
- 0 <= len(s) <= 100
- 如果你不使用额外的数据结构,会很加分。
题目来源:LeetCode
解法一
判断一个字符串中所有字符是否唯一,最简单的暴力求解就是两两对比是否相同,即双重循环,但是算法复杂度为 O(n^2),性能也是最低的。如果字符串的长度是比较小的话,此算法也是勉强可以使用的。
package com.chenpi;
/**
* @Description 实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
* @Author Mr.nobody
* @Date 2021/4/18
* @Version 1.0
*/
public class StrIsUnique {
public boolean isUnique(String astr) {
// 字符串为null或者为空,自然没有字符重复,即唯一
if (null == astr || 0 == astr.length()) {
return true;
}
// 双重循环,两两对比
for (int i = 0; i < astr.length() - 1; i++) {
for (int j = i + 1; j < astr.length(); j++) {
if (astr.charAt(i) == astr.charAt(j)) {
return false;
}
}
}
return true;
}
public static void main(String[] args) {
String astr = "leetcode";
StrIsUnique strIsUnique = new StrIsUnique();
System.out.println(strIsUnique.isUnique(astr));
}
}
解法二
既然是判断唯一性,那我们可以遍历每一个字符,然后通过某种规则将它们放入指定位置,因为相同字符肯定会被放到相同的位置,我们只需要判断放入此位置之前是否有字符放入过,如果有,就代表有重复的字符。借助散列表这种数据结构就能达到这种效果。
package com.chenpi;
import java.util.HashMap;
import java.util.Map;
/**
* @Description 实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
* @Author Mr.nobody
* @Date 2021/4/18
* @Version 1.0
*/
public class StrIsUnique {
public boolean isUnique(String astr) {
// 字符串为null或者为空,自然没有字符重复,即唯一
if (null == astr || 0 == astr.length()) {
return true;
}
Map<Character, Integer> map = new HashMap<>(astr.length() + 1);
// 遍历每一个字符,从map中判断是否存在相同的字符
for (int i = 0; i < astr.length(); i++) {
// 存在相同的字符
if (null != map.get(astr.charAt(i)) && map.get(astr.charAt(i)) == 1) {
return false;
}
// 在map中不存在此字符,放入map中
map.put(astr.charAt(i), 1);
}
return true;
}
public static void main(String[] args) {
String astr = "陈皮的JavaLib";
StrIsUnique strIsUnique = new StrIsUnique();
System.out.println(strIsUnique.isUnique01(astr));
}
}
解法三
如果我们不再借助其他数据结构,如何解法呢?因为要求唯一性,肯定要有字符比较的。解法二我们借助了散列表这种数据结构,结果内存消耗方面只击败了27.28%的用户。
假设字符串中的字符是26个小写字母,解法二是将每一个字符放入散列表中,如果散列表中每一个位置都没有重复的字符,则唯一性。那我们可以将每一个字符映射到一个二进制数组中,通过与运算,如果相同位置都为1,则结果为1,则代表有重复字符。
借助一个初始值为0的int变量mark,二进制形式为0000...0000,遍历每一个字符,计算字符与a
字符的距离move_bit,然后使用左移运算符1 << move_bit创建对应下标为1,其余下标为0的数num。将num与mark做与运算,如果结果不为0,则代表有重复字符。如果结果为0,则代表这个字符之前没出现过,将num和mark通过或运算的结果赋值给mark,即在mark中将此字符的对应下标的值设为1。
package com.chenpi;
import java.util.HashMap;
import java.util.Map;
import java.util.function.BinaryOperator;
/**
* @Description 实现一个算法,确定一个字符串 s 的所有字符是否全都不同。
* @Author Mr.nobody
* @Date 2021/4/18
* @Version 1.0
*/
public class StrIsUnique {
public boolean isUnique02(String astr) {
// 字符串为null或者为空,自然没有字符重复,即唯一
if (null == astr || 0 == astr.length()) {
return true;
}
int mark = 0;
int num = 0;
// 遍历每一个字符
for (int i = 0; i < astr.length(); i++) {
num = 1 << (astr.charAt(i) - 'a');
// 通过与运算判断对应下标是否都为1,即是否有相同字符
if ((mark & num) != 0) {
return false;
}
// 在map中将对应下标置为1
mark |= num;
}
return true;
}
public static void main(String[] args) {
String astr = "javalib";
StrIsUnique strIsUnique = new StrIsUnique();
System.out.println(strIsUnique.isUnique02(astr));
}
}
上一题与下一题
上一题:LeetCode 每日一题「实现 strStr()」
LeetCode 每日一题「判定字符是否唯一」的更多相关文章
-
Leetcode 面试题 01.01. 判定字符是否唯一
实现一个算法,确定一个字符串 s 的所有字符是否全都不同. 示例 1: 输入: s = "leetcode"输出: false 示例 2: 输入: s = "abc&qu ...
-
【JavaScript】Leetcode每日一题-青蛙过河
[JavaScript]Leetcode每日一题-青蛙过河 [题目描述] 一只青蛙想要过河. 假定河流被等分为若干个单元格,并且在每一个单元格内都有可能放有一块石子(也有可能没有). 青蛙可以跳上石子 ...
-
【python】Leetcode每日一题-扰乱字符串
[python]Leetcode每日一题-扰乱字符串 [题目描述] 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行 ...
-
【JavaScript】Leetcode每日一题-在D天内送包裹的能力
[JavaScript]Leetcode每日一题-在D天内送包裹的能力 [题目描述] 传送带上的包裹必须在 D 天内从一个港口运送到另一个港口. 传送带上的第 i 个包裹的重量为 weights[i] ...
-
【JavaScript】【dp】Leetcode每日一题-解码方法
[JavaScript]Leetcode每日一题-解码方法 [题目描述] 一条包含字母 A-Z 的消息通过以下映射进行了 编码 : 'A' -> 1 'B' -> 2 ... 'Z' -& ...
-
【JavaScript】【KMP】Leetcode每日一题-实现strStr()
[JavaScript]Leetcode每日一题-实现strStr() [题目描述] 实现 strStr() 函数. 给你两个字符串 haystack 和 needle ,请你在 haystack 字 ...
-
【JavaScript】Leetcode每日一题-移除元素
[JavaScript]Leetcode每日一题-移除元素 [题目描述] 给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度. 不要使用 ...
-
【python】Leetcode每日一题-删除有序数组中的重复项
[python]Leetcode每日一题-删除有序数组中的重复项 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现一次 ,返回删除后数组的新长度. 不要 ...
-
[LeetCode每日一题]153.寻找旋转排序数组中的最小值
[LeetCode每日一题]153.寻找旋转排序数组中的最小值 问题 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组.例如,原数组 nums = [0,1, ...
随机推荐
-
[Python]实现简单决策树
基本思路: 通过香农熵来决定每一层使用哪一种标签做分类,分类后,通过多数表决法来决定该层两个节点的类别.每次消耗一个标签,所以一共需要递归"标签个数"层. # -*- coding ...
-
Dojo
dojo的类机制支持类声明.继承.调用父类方法等功能.dojo在底层实现上是通过操作原型链来实现其类机制的,而在实现继承时采用类式继承的方式.值得一提的是,dojo的类机制允许进行多重继承(注意,只有 ...
-
Cygwin的安装
Android开发要用到NDK,装了一个虚拟机,老是不行. 后来安装了一个cygwin,安装完毕后unset home,再export NDK,就可以使用了,非常方便,不用像虚拟机那样经常切换.
-
nodejs实现Websocket的数据接收发送
在去年的时候,写过一篇关于websocket的博文:http://www.cnblogs.com/axes/p/3586132.html ,里面主要是借助了nodejs-websocket这个插件,后 ...
-
vim 图解常用快捷键操作
图片太大,可以将图片另存后看或者右键点击,选择查看图片.
-
thinkinginjava学习笔记03_基本语法
由于java是c系语言,基本保留c语言的所有基本操作,就快速过一下: java中的基本操作符仅仅对基本类型有效:=.==.!=对所有对象有效(值传递),String类支持+.+=; 在对基本数据进行算 ...
-
c# 类属性和方法
属性 public 类字段 就相当于c#里面暴露给外面的属性 类似nodejs的 module.exports 但是属性又不同于普通的字段,属性只是外部包装字段 没有自己的任何含量 类似退换后的方法. ...
-
Python学习—基础篇之文件操作
文件操作 文件操作也是编程中需要熟练掌握的技能,尤其是在后台接口编写和数据分析过程中,对各种类型的文件进行操作,获取文件信息或者对信息进行存储是十分重要的.本篇博客中将主要对常见的文本格式文件和Exc ...
-
吴恩达讲了干货满满的一节全新AI课,全程手写板书充满诚意非常干货
吴恩达讲了干货满满的一节全新AI课,全程手写板书充满诚意非常干货 摘要: 目前,AI技术做出的经济贡献几乎都来自监督学习,也就是学习从A到B,从输入到输出的映射.现在,监督学习.迁移学习.非监督学习. ...
-
Alpha版本冲刺(四)
目录 组员情况 组员1(组长):胡绪佩 组员2:胡青元 组员3:庄卉 组员4:家灿 组员5:凯琳 组员6:丹丹 组员7:何家伟 组员8:政演 组员9:鸿杰 组员10:刘一好 组员:何宇恒 展示组内最新 ...