LeetCode 每日一題「判定字符是否唯一」


我是陳皮,一個在互聯網 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 每日一題「判定是否互為字符重排」


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM