首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

LeetCode 345. 反轉字符串中的元音字母:雙指針原地算法 Java 實現

     編輯:Java 綜合教學

LeetCode 345. 反轉字符串中的元音字母:雙指針原地算法 Java 實現

題目描述

編寫函數,接收一個字符串,僅反轉其中的元音字母 (a, e, i, o, u, A, E, I, O, U),其他字符位置不變。

示例 1:"hello" → "holle" (e, o 互換)

示例 2:"leetcode" → "leotcede" (e, o, e, e → e, e, o, e)

核心思路:雙指針原地交換

字符串不可變,轉 char[] 操作。左右雙指針向中間掃描,遇到元音則交換,非元音則移動指針。

Java 實現 (標準解法)

public String reverseVowels(String s) {
    if (s == null || s.length() <= 1) return s;
    
    // 元音查找集:O(1) 判斷
    Set vowels = new HashSet<>(Arrays.asList('a','e','i','o','u','A','E','I','O','U'));
    // 或用 boolean[128] 數組更快 (ASCII)
    // boolean[] isVowel = new boolean[128];
    // for (char c : "aeiouAEIOU".toCharArray()) isVowel[c] = true;
    
    char[] chars = s.toCharArray();
    int left = 0, right = chars.length - 1;
    
    while (left < right) {
        // 左指針找元音
        while (left < right && !vowels.contains(chars[left])) left++;
        // 右指針找元音
        while (left < right && !vowels.contains(chars[right])) right--;
        
        // 交換
        if (left < right) {
            char temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;
            left++;
            right--;
        }
    }
    return new String(chars);
}

優化版:boolean 數組替代 HashSet (極致性能)

public String reverseVowels(String s) {
    if (s == null || s.length() <= 1) return s;
    
    // ASCII 範圍內 boolean 數組查找最快,無哈希開銷
    boolean[] isVowel = new boolean[128];
    for (char c : "aeiouAEIOU".toCharArray()) isVowel[c] = true;
    
    char[] chars = s.toCharArray();
    int left = 0, right = chars.length - 1;
    
    while (left < right) {
        while (left < right && !isVowel[chars[left]]) left++;
        while (left < right && !isVowel[chars[right]]) right--;
        
        if (left < right) {
            char temp = chars[left];
            chars[left] = chars[right];
            chars[right] = temp;
            left++;
            right--;
        }
    }
    return new String(chars);
}

複雜度分析

  • 時間:O(n) — 單次遍歷,每字符最多訪問常數次
  • 空間:O(n) — char[] 複製 (Java 字符串不可變) + O(1) 輔助空間

關鍵點總結

技術點說明
雙指針左右夾適,原地交換,單次掃描完成
元音判斷Set/boolean[] 實現 O(1) 查找,避免字符串 indexOf O(k)
邊界條件空串、單字符、無元音、全元音、左右指針相遇
字符串不可變必須 toCharArray() 操作,最後 new String() 構建結果
大小寫敏感題目包含大小寫元音,集合/數組需同時包含

擴展變體思考

  • Unicode 字符串:boolean[] 不適用,改用 HashSet<Character> 或 Character.toLowerCase 統一判斷
  • 自定義元音集合:作為參數傳入,提高復用性
  • 流式處理:不可原地修改,需緩衝區或雙端隊列
  • 原地修改 char[] 參數:若 API 允許傳入可變數組,可省去複製開銷

面試加分回答

「雙指針左右掃描,boolean[128] 數組 O(1) 判斷元音,遇到則交換並移動指針。時間 O(n),空間 O(n) (char[] 複製)。注意字符串不可變需轉數組,大小寫全覆蓋,邊界條件 left

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved