Heterogram (เฮเทอโรแกรม) คือคำหรือวลีที่ ไม่มีตัวอักษรซ้ำกันเลย ทุกตัวอักษรต้องไม่ซ้ำ (Case-insensitive ปกติ)
ตัวอย่าง Heterogram
- "Mobile" → m,o,b,i,l,e ✓
- "Cry" → c,r,y ✓
- "Laptop" → l,a,p,t,o,p ✗ (p ซ้ำ)
- "Background" → b,a,c,k,g,r,o,u,n,d ✓
อัลกอริทึม: ใช้ Boolean Array (Bit Vector)
using System;
public class GFG
{
public static bool CheckHeterogram(string str)
{
if (string.IsNullOrEmpty(str)) return true;
// ใช้ bit mask แทน array - ประหยัดหน่วยความจำและเร็วกว่า
int checker = 0;
foreach (char c in str.ToLower())
{
if (c < 'a' || c > 'z') continue; // ข้าม non-alphabet
int bitIndex = c - 'a';
int mask = 1 << bitIndex;
if ((checker & mask) != 0)
return false; // พบตัวซ้ำ
checker |= mask; // ทำเครื่องหมายว่าพบแล้ว
}
return true;
}
public static void Main()
{
string[] tests = { "mobile", "laptop", "background", "hello", "world" };
foreach (var test in tests)
{
Console.WriteLine($"\"{test}\" => {(CheckHeterogram(test) ? "Heterogram ✓" : "Not Heterogram ✗")}");
}
}
}
ผลลัพธ์
"mobile" => Heterogram ✓
"laptop" => Not Heterogram ✗
"background" => Heterogram ✓
"hello" => Not Heterogram ✗
"world" => Heterogram ✓
วิธี Alternative: ใช้ HashSet (อ่านง่ายกว่า)
public static bool IsHeterogramHashSet(string str)
{
var seen = new HashSet();
foreach (char c in str.ToLower())
{
if (c < 'a' || c > 'z') continue;
if (!seen.Add(c)) return false; // Add คืน false ถ้ามีอยู่แล้ว
}
return true;
}
วิธี LINQ (สั้นที่สุด)
public static bool IsHeterogramLinq(string str)
{
var letters = str.ToLower().Where(c => c >= 'a' && c <= 'z');
return letters.Distinct().Count() == letters.Count();
}
เปรียบเทียบ
| วิธี | Time | Space | ความเข้าใจง่าย |
|---|---|---|---|
| Bit Mask | O(n) | O(1) - 1 int | กลาง |
| HashSet | O(n) | O(k) k=unique chars | สูง |
| LINQ | O(n) | O(n) | สูงสุด |
กรณีใช้งานจริง
- Word Games: Scrabble, Boggle, Wordle variants
- Cryptography: ตรวจสอบ Key ที่ไม่มีตัวซ้ำ
- Linguistics: ศึกษาคำที่เป็น Heterogram (Isogram)
- Password Policy: บังคับให้รหัสผ่านไม่มีตัวอักษรซ้ำ