100天算法入门 - 每日三题 - Day7验证回文串只出现一次的数字多数元素
Posted 哪 吒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了100天算法入门 - 每日三题 - Day7验证回文串只出现一次的数字多数元素相关的知识,希望对你有一定的参考价值。
大家好,我是哪吒,一个热爱编码的Java工程师,本着“欲速则不达,欲达则欲速”的学习态度,在程序猿这条不归路上不断成长,所谓成长,不过是用时间慢慢擦亮你的眼睛,少时看重的,年长后却视若鸿毛,少时看轻的,年长后却视若泰山,成长之路,亦是渐渐放下执念,内心归于平静的旅程。
也许,我们永远都不会知道自己能走到何方,遇见何人,最后会变成什么样的人,但一定要记住,能让自己登高的,永远不是别人的肩膀,而是挑灯夜战的自己,人生的道路刚刚启程,当你累了倦了也不要迷茫,回头看一看,你早已不再是那个年少轻狂的少年。
大连星海公园
算法是进阶架构师的基础,基础不牢,地动山摇,2021-8-14起开始刷题,目标100天,300道LeetCode算法题,分享是学习的最好方式,加油,嗨起来。
1、LeetCode 125.验证回文串
题目
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
小编菜解
public static boolean isPalindrome(String s) {
// 通过正则表达式只获取数字和字母部分
s=s.replaceAll("[^a-zA-Z0-9]","").toLowerCase();
// 回文串是指中间分隔,前面的和后面的revert一样
int length = s.length();
String left = "";
String right = "";
if (length%2 != 0){
left = s.substring(0,length/2);
right = s.substring(length/2+1,length);
right = new StringBuilder(right).reverse().toString();
}else{
int mid = length/2;
left = s.substring(0,mid);
right = s.substring(mid,length);
right = new StringBuilder(right).reverse().toString();
}
return left.equals(right);
}
虽然执行通过了,但效率堪忧啊。
思路及算法
“回文串”是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
所以为什么要中间分隔呢,直接反转,对比反转后的和初始的,不就完事了?菜啊。
小菜改进版
public static boolean isPalindrome3(String s) {
// 通过正则表达式只获取数字和字母部分
s=s.replaceAll("[^a-zA-Z0-9]","").toLowerCase();
return s.equals(new StringBuilder(s).reverse().toString());
}
效率依旧很低,因为正则的缘故吧。
大佬指点江山
public static boolean isPalindrome(String s) {
StringBuilder builder = new StringBuilder();
for (int i = 0;i<s.length();i++){
char c = s.charAt(i);
if (Character.isLetterOrDigit(c)){
builder.append(Character.toLowerCase(c));
}
}
return builder.toString().equals(builder.reverse().toString());
}
差距还是很明显的,能不用正则就不要用正则表达式。
2、LeetCode 136.只出现一次的数字
题目
给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
小编菜解
/**
* 暴力算法,当前元素与其它元素进行比较,如果有相等的,则表示出现不止一遍,不等,则表示唯一
*/
public static int singleNumber(int[] nums) {
for (int i = 0; i < nums.length; i++) {
boolean flag = true;
for (int j = 0; j < nums.length; j++) {
if (i != j){
if (nums[i] == nums[j]){
flag = false;
break;
}
}
}
if (flag){
return nums[i];
}
}
return 0;
}
大佬指点江山
参与运算的两个值,如果两个相应bit位相同,则结果为0,否则为1。
public static int singleNumber(int[] nums) {
int single = 0;
for (int num : nums) {
single ^= num;
}
return single;
}
3、LeetCode 169.多数元素
题目
给定一个大小为 n 的数组,找到其中的多数元素。多数元素是指在数组中出现次数 大于 ⌊ n/2 ⌋ 的元素。
你可以假设数组是非空的,并且给定的数组总是存在多数元素。
小编菜解
public static int majorityElement(int[] nums) {
if (nums.length == 1){
return nums[0];
}
for (int i = 0; i < nums.length; i++) {
int sum = 1;
for (int j = 0; j < nums.length; j++) {
if (i != j){
if (nums[i] == nums[j]){
sum++;
}
}
}
if (sum > nums.length/2){
return nums[i];
}
}
return 0;
}
小编菜解改进版
public static int majorityElement(int[] nums) {
Map<Integer,Integer> map = new HashMap<>();
for (int i = 0; i < nums.length; i++) {
if (!map.containsKey(nums[i])){
map.put(nums[i],1);
}else{
map.put(nums[i],map.get(nums[i]) + 1);
}
}
for (Map.Entry<Integer,Integer> entry : map.entrySet()){
if(entry.getValue() > nums.length/2){
return entry.getKey();
}
}
return 0;
}
执行用时少了不止一点点啊,进步显著,加油。
大佬指点江山
public static int majorityElement(int[] nums) {
Arrays.sort(nums);
int mid = nums.length/2;
return nums[mid];
}
纳尼?还可以这样玩?思考思考,还真是这样,因为要取得众数,众数一定大于半数,如果排序完之后,这个数组的最中间肯定属于众数,牛逼plus。
推荐阅读
【100天算法入门 - 每日三题 - Day1】二叉树的中序遍历、两数之和、整数反转
【100天算法入门 - 每日三题 - Day2】二分查找、第一个错误的版本、搜索插入位置
【100天算法入门 - 每日三题 - Day3】回文数、罗马数字转数字、最大公共前缀
【100天算法入门 - 每日三题 - Day4】有效的括号、删除有序数组中的重复项、实现strStr
以上是关于100天算法入门 - 每日三题 - Day7验证回文串只出现一次的数字多数元素的主要内容,如果未能解决你的问题,请参考以下文章
100天算法入门 - 每日三题 - Day12Nim游戏3的幂4的幂
100天算法入门 - 每日三题 - Day15判断子序列最长回文数Fizz Buzz
100天算法入门 - 每日三题 - Day16第三大的数字符串中的单词数排列硬币
100天算法入门 - 每日三题 - Day5最后一个单词的长度相同的树买卖股票的最佳时机