前言:主要目的是為了持續輸出,用淺顯易懂,各種各樣的方式來解析演算法題,同時提高演算法能力。答主的水平也有限,大家共同進步。
面試題01.01. 判定字元是否唯一題目:
實現一個演算法,確定一個字串s的所有字元是否全都不同示例1:輸入:s="leetcode"輸出:false
示例2:
輸入:s="abc"輸出:true
限制0<=len(s)<=100如果不使用額外的資料結構,會很加分。這是一道很簡單的演算法題,解題方法有很多,我們介紹幾種不同思路的演算法,以後遇到相同型別的演算法題,我也會更新在此帖下面。
先來一種簡單、出其不意的方式。
1. 巧用indexOf與lastIndexOfvar isUnique = function(astr) { for ( let i=0;i<astr.length;i++ ) { if ( astr.indexOf(astr[i]) !== astr.lastIndexOf(astr[i]) ) { return false; } } return true; };
執行用時:80 ms, 在所有 JavaScript 提交中擊敗了67%的使用者記憶體消耗:37.6 MB, 在所有 JavaScript 提交中擊敗了70%的使用者
解析:indexOf和lastIndexOf這兩個方法,顧名思義,前者用來找到某個值是否存在於該陣列(字串)中,如果找到,返回某值第一次出現的下標,後者相同,區別就是前者是正序查詢(也就是從字串的第一位開始進行對比),後者是倒序查詢(從字串的最後一位開始對比)。由此可得,如果某個值在該陣列(字串)中只出現了一次,那麼他正序查到和倒序查詢返回的下標肯定是一致的,反之則證明至少出現了兩次。
所以,當正序和倒序的座標不相同時,我們可以直接返回false,遊戲結束;當整個迴圈都進行完畢,還是結束時,我們就可以判定該字串中沒有相同的值了,可直接返回true。
2. 利用ES6新特性Setvar isUnique = function(astr) { return new Set([...astr]).size === astr.length;};
執行用時:88 ms, 在所有 JavaScript 提交中擊敗了28%的使用者記憶體消耗:37.7 MB, 在所有 JavaScript 提交中擊敗了32%的使用者
可謂是失之毫釐,差之千里。相差了0.08ms而已...
解析:Set是ES6提供的資料結構,類似於陣列,但是成員的值都是唯一的,沒有重複的值。 -- ES6入門(阮一峰)
具體關於Set的介紹,各位看官如果有興趣的話,可以去百度上搜一下這本書啊,都有詳細的介紹,也可以購買實體書籍。
所以,我們只需要判定長度就可以了,如果相同,證明沒有重複的元素,反之相反。
3. 利用indexOf特性其實解法1和2都不是最優解,都是利用了原生的一些特性,但解法1顯然還有最佳化的空間。
各位看官是否還記得indexOf其實還有第二個引數。
stringObject.indexOf(searchvalue,fromindex)searchvalue -> 必需。規定需檢索的字串值。fromindex -> 可選的整數引數。規定在字串中開始檢索的位置。它的合法取值是 0 到 stringObject.length - 1。如省略該引數,則將從字串的首字元開始檢索。 --w3school.com.cn
上面這一段話,就是直接從網站上拿下來的,我們可以利用該方法的第二個引數來做文章完成此次題目。
如果某字串中沒有相同的字母,那我們從該字母所在的位置後開始查詢,將會查不到結果,所以我們可以利用該特性算出結果,同時也減少了indexOf的計算次數。
程式碼如下:
var isUnique = function(astr) { for(let i in astr){ let index=astr.indexOf(astr[i],parseInt(i)+1); if(index>-1){ return false } } return true; };
執行用時:80 ms, 在所有 JavaScript 提交中擊敗了66.01%的使用者記憶體消耗:37.3 MB, 在所有 JavaScript 提交中擊敗了96.74%的使用者
其實這道題的解法還有很多,比如利用迴圈來代替indexOf,或者用一個新物件來代替new Set去重,思路都大體相同,所以在此不再重複,方法千千萬萬,能夠真正為自己所用,才是目的。
總結總結一下我們三種方法的三種思路吧,在遇到同種型別的題時,我們也可以輕鬆寫出答案。
解法一利用了倒序和正序的差值來確定是否具有唯一性解法二利用了去重後的長度和原始長度的對比解法三透過去掉自身後找與自身重複的方法來判定唯一性突然想到了這道題的延伸題目:
實現一個演算法,確定一個字串s的所有字元是否全都不同,如果有相同的字母,請算出相同的次數。
這個題目就作為我們本次的延伸題目吧,答案會放在之後的文章中。