目次
242. 有効な異音
質問の意味:
2 つの文字列
s
と が 与えられた場合、 が のアナグラムで あるかどうかをt
判断する関数を作成します 。t
s
注:
s
と の 各文字がt
同じ回数出現する 場合 、s
と はt
互いのアナグラムであると言われます。
【入力サンプル】
s="アナグラム"、t="ナガラム"
[出力サンプル] true
問題解決のアイデア:
これは比較的単純で、2 つの文字列内の文字の出現数を記録する配列を定義します。
配列 alphaNum は 0 に初期化され、文字列はその ++ とアライメントを担当します。
アナグラムの場合、alphaNum の最終値は間違いなくすべて 0 になります。
class Solution {
public boolean isAnagram(String s, String t) {
//s和t都是小写字母,每个字符出现次数相同,当两个字符长度不一样时也不行
if(s.length() != t.length()){
return false;
}
int[] alphaNum = new int[26];
for(int i=0;i<s.length();++i){
++alphaNum[s.charAt(i) - 'a'];
}
for(int i = 0;i<t.length();++i){
--alphaNum[t.charAt(i) - 'a'];
if(alphaNum[t.charAt(i) - 'a'] < 0){
return false;
}
}
return true;
}
}
タイム: 82.24% を達成
メモリ: 71.71% 上回る
49. アルファベットのアナグラムのグループ化
質問の意味:
文字列の配列が与えられ、 アナグラムを組み合わせるように求められます 。結果のリストは任意の順序で返すことができます。
アナグラムは、 元の単語のすべての文字を並べ替えることによって得られる新しい単語です。
【入力サンプル】
strs=["食べる","お茶","タン","食べる","ナット","コウモリ"]
[出力サンプル][["eat","tea","ate"],["tan","nat"],["bat"]]
問題解決のアイデア:
ソート + ハッシュ: 文字列 str を取得してソートします。たとえば、ソート後は「eat」が「aet」になり、 map.getOrDefault(key, new Array<>()) を使用して
aet をマップ内のキーとして保存します。このキーがマップ内に存在する場合は、そのキー (この質問ではリスト) に対応する値が返されます。そのようなキーが存在しない場合は、初めて出現したことが証明され、新しいリストが作成されます。
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
//方法一:排序+哈希
Map<String,List<String>> map = new HashMap<String,List<String>>();
for(String str: strs){
char[] array = str.toCharArray();
Arrays.sort(array);
String key = new String(array);
List<String> list = map.getOrDefault(key,new ArrayList<String>());
list.add(str);
map.put(key,list);
}
return new ArrayList<List<String>>(map.values());//把map转成对应格式
}
}
時間: 99.24% を達成
メモリ: 40.02% で負けました
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
//方法二:计数+哈希
/**
拿到一个字符串str,按上一题的思路统计出现的次数和字母作为key:如eat为a1e1t1
用计数统计来替换掉数组排序
之后是一样的操作
使用map.getOrDefault(key,new Array<>());
如果map中存在此key,会将key对应的value(本题是list)返回了,如果没有此key,证明是第一次遇到,new一个list
*/
Map<String,List<String>> map = new HashMap<String,List<String>>();
for(String str: strs){
int[] count = new int[26];
for(int i=0;i<str.length();++i){
++count[str.charAt(i)-'a'];
}
//合成key
StringBuffer key = new StringBuffer();
for(int i=0;i<26;++i){
if(count[i]!=0){
key.append((char)(i+'a'));//字母
key.append(count[i]);//次数
}
}
String strKey = key.toString();
List<String> list = map.getOrDefault(strKey,new ArrayList<String>());
list.add(str);
map.put(strKey,list);
}
return new ArrayList<List<String>>(map.values());//把map转成对应格式
}
}
202.ハッピーナンバー
質問の意味:
n
数値が幸せな数値かどうかを判断するアルゴリズムを作成します 。「ハッピーナンバー」は 次のように定義されます。
- 正の整数の場合、数値は各位置の桁の二乗の合計で置き換えられます。
- 次に、数値が 1 に達するまでこのプロセスを繰り返します。または、 無限ループ しても 1 に到達しない場合があります。
- このプロセスの結果が 1 であれば 、この数字は幸せな数字です。
幸せな数値
n
で あれば それを返し 、そうでない場合はそれを返します 。true
false
【入力サンプル】n=19
[出力サンプル] true
問題解決のアイデア:
ハッシュコレクション
n の各桁の二乗和を継続的に計算し、そのたびに計算した数を集合に格納し、n が 1 に等しくないときに、現在計算されている n がすでに集合に格納されていることがわかれば、次のことが証明されます。無限ループに陥ってしまったのです。
class Solution {
private int getNext(int n) {
int totalSum = 0;
while (n > 0) {
int d = n % 10;
n = n / 10;
totalSum += d * d;
}
return totalSum;
}
public boolean isHappy(int n) {
Set<Integer> seen = new HashSet<>();
while (n != 1 && !seen.contains(n)) {
seen.add(n);
n = getNext(n);
}
return n == 1;
}
}
タイム: 85.70% を達成
メモリ: 81.73% 上回る
219. 繰り返しの要素があるⅡ
質問の意味:
整数配列
nums
と integer が与えられた場合、 と を 満たす 2 つの異なるインデックスの合計が配列 内にk
存在するかどうかを判断します 。存在する場合は return 、存在しない場合は return 。i
j
nums[i] == nums[j]
abs(i - j) <= k
true
false
【入力例】 nums=[1,2,3,1],k=3
[出力サンプル] true
問題解決のアイデア:
nums[i] をキー、i を値として使用します。nums[j] == nums[i] の場合、i と j の差を計算します。k の要件を満たさない場合は、nums の値を変更します。 [i] から j。配列をトラバースするとき、ポインタは後方に進み続けるためです。
class Solution {
public boolean containsNearbyDuplicate(int[] nums, int k) {
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
int temp;
for(int i=0;i<nums.length;++i){
temp = nums[i];
if(map.containsKey(temp) && (i - map.get(temp) <=k)){
return true;
}
map.put(temp,i);
}
return false;
}
}
タイム: 85.19% を達成
メモリ: 47.36% の差
383.身代金の手紙
質問の意味:
ransomNote
および という 2 つの文字列が与えられた場合magazine
、ransomNote
それらがmagazine
内部の文字で構成できるかどうかを判断します。可能な場合は戻り
true
、そうでない場合は戻りますfalse
。
magazine
の各文字は でransomNote
1 回だけ使用できます。ヒント:
1 <= ransomNote.length, magazine.length <= 105
ransomNote
magazine
英小文字で構成されてい ます
【入力例】 ransomNote="a"、magazine = "b"
[出力例] false
問題解決のアイデア:
マガジンでの各キャラクターの使用回数を直接カウントしますが、randomNoteでの各キャラクターの使用回数以上になることはありますか?
class Solution {
public boolean canConstruct(String ransomNote, String magazine) {
if(magazine.length() < ransomNote.length()){
return false;
}
int[] num = new int[26];
for(int i=0;i<magazine.length();++i){
++num[magazine.charAt(i) - 'a'];
}
for(int i=0;i<ransomNote.length();++i){
--num[ransomNote.charAt(i) - 'a'];
if(num[ransomNote.charAt(i) - 'a'] < 0){
return false;
}
}
return true;
}
}
時間: 99.33% を達成
メモリ: 98.96% を超える
205. 同型文字列
質問の意味:
2 つの文字列
s
と が与えられた場合t
、それらが同型であるかどうかを判断します。
s
の文字を特定のマッピング関係に従って置き換えることができる 場合t
、2 つの文字列は同形です。文字が出現するたびに、文字の順序を変更せずに別の文字にマッピングする必要があります。異なる文字を同じ文字にマッピングすることはできません。同じ文字は同じ文字にのみマッピングでき、文字はそれ自体にマッピングできます。
ヒント:
1 <= s.length <= 5 * 104
t.length == s.length
s
t
有効な ASCII 文字で構成されてい ます
【入力例】 s="egg",t="add"
[出力サンプル] true
問題解決のアイデア:
s.charAt(i) はキー、t.charAt(i) は値であり、一貫している必要があります。
class Solution {
public boolean isIsomorphic(String s, String t) {
if(s==null){
return true;
}
Map<Character,Character> map = new HashMap<Character,Character>();
for(int i=0;i<s.length();++i){
char key = s.charAt(i);
if(!map.containsKey(key)){
//如果这个key和value都不存在的话,那就直接添加key,value
//key不存在,但是已经有value了,也不行
if(map.containsValue(t.charAt(i))){
return false;
}
map.put(key,t.charAt(i));
}else{
if(t.charAt(i) != map.get(key)){
return false;
}
}
}
return true;
}
}
タイム: 58.80%を達成
メモリ: 76.72% 上回る
290. 言葉のルール
質問の意味:
pattern
pattern
と string が 与えられた場合s
、s
それが同じパターンに従っているかどうかを判断します。ここでの 「フォロー」は 完全一致を指します。たとえば、
pattern
の各文字と文字列 の空でない各単語s
の間には双方向の接続があります。ヒント:
1 <= pattern.length <= 300
pattern
小文字の英字のみが含まれています1 <= s.length <= 3000
s
小文字の英字のみが含まれており、' '
s
先頭または末尾のスペースのペアは含まれませんs
の各単語は 単一のスペース で区切られます
【入力例】 pattern="abba"、s="犬猫猫犬"
[出力サンプル] true
問題解決のアイデア:
205 と似ています。値が文字から文字列に変わる点を除き、同型文字列です。
class Solution {
public boolean wordPattern(String pattern, String s) {
if(s == null){
return true;
}
Map<Character,String> map = new HashMap<Character,String>();
String[] str = s.split(" ");//根据空格提取单词
if(pattern.length() != str.length){
return false;
}
for(int i=0;i<pattern.length();++i){
char key = pattern.charAt(i);
if(map.containsKey(key) && !(str[i].equals(map.get(key)))){
return false;
}
if(!map.containsKey(key) && map.containsValue(str[i])){
return false;
}
map.put(key,str[i]);
}
return true;
}
}
タイム: 55.43% を達成
メモリ: 61.55% 劣る