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天算法入门 - 每日三题 - Day5】最后一个单词的长度、相同的树、买卖股票的最佳时机

【100天算法入门 - 每日三题 - Day6】对称二叉树、二叉树的最大深度、将有序数组转换为二叉搜索树

以上是关于100天算法入门 - 每日三题 - Day7验证回文串只出现一次的数字多数元素的主要内容,如果未能解决你的问题,请参考以下文章

100天算法入门 - 每日三题 - Day12Nim游戏3的幂4的幂

100天算法入门 - 每日三题 - Day15判断子序列最长回文数Fizz Buzz

100天算法入门 - 每日三题 - Day16第三大的数字符串中的单词数排列硬币

100天算法入门 - 每日三题 - Day5最后一个单词的长度相同的树买卖股票的最佳时机

100天算法入门 - 每日三题 - Day13反转字符串反转字符串中的元音字母两个数组的交集

100天算法入门 - 每日三题 - Day17找到所有数组中消失的数最小操作次数使数组元素相等分发饼干