欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++實現回文串判斷的兩種高效方法

 更新時間:2025年03月03日 16:46:04   作者:倔強的石頭_  
文章介紹了兩種判斷回文串的方法:解法一通過創(chuàng)建新字符串來處理,解法二在原字符串上直接篩選判斷,兩種方法都使用了雙指針法,文中通過代碼示例講解的非常詳細,需要的朋友可以參考下

一、問題描述

在字符串處理中,判斷一個字符串是否為回文串是一個經典問題。

本題有特殊要求:在將所有大寫字符轉換為小寫字符、并移除所有非字母數字字符之后,如果短語正著讀和反著讀都一樣,則認為該短語是一個回文串。字母和數字都屬于字母數字字符。

示例

  • 輸入: s = "A man, a plan, a canal: Panama",輸出:true,解釋:處理后得到 "amanaplanacanalpanama" 是回文串。
  • 輸入:s = "race a car",輸出:false,解釋:處理后得到 "raceacar" 不是回文串。
  • 輸入:s = " ",輸出:true,解釋:移除非字母數字字符后,s 是一個空字符串 "",空字符串正著反著讀都一樣,所以是回文串。

 原題鏈接 

125. 驗證回文串 - 力扣(LeetCode)

二、解法一:將字母數字連接到新的 string

思路

這種方法的核心思想是先遍歷原字符串,把其中的字母數字字符提取出來,同時將大寫字母轉換為小寫字母,存儲到一個新的字符串 tmp 中

然后再對新字符串 tmp 進行回文判斷

代碼實現

#include <iostream>
#include <string>
 
class Solution {
public:
    bool isPalindrome(string s) //第一種方式 將字母數字連接到新的string
    {
        string tmp;
        string::iterator left = s.begin();
        string::iterator right = s.end();
 
        while (left != right)//第一次遍歷,所有字母數字轉入新string,并且統(tǒng)一為小寫
        {
            if ((*left >= '0' && *left <= '9') || (*left >= 'a' && *left <= 'z'))
                tmp += *left;
            if (*left >= 'A' && *left <= 'Z')
                tmp += (*left + 32);
            ++left;
        }
 
        if (tmp.empty())//如果新string為空,則判定為回文串
            return true;
 
        left = tmp.begin();
        right = tmp.end() - 1;
        while (left <= right)//第二次遍歷 左右迭代器逐個對比
        {
            if (*left == *right)
            {
                ++left;
                --right;
            }
            else
                return false;
        }
        return true;
    }
};

代碼解釋

  1. 提取字母數字并轉換大小寫
    • 定義一個空字符串 tmp 用于存儲處理后的字符。
    • 使用迭代器 left 遍歷原字符串 s,當遇到數字('0' 到 '9')或小寫字母('a' 到 'z')時,直接添加到 tmp 中;當遇到大寫字母('A' 到 'Z')時,將其 ASCII 碼值加 32 轉換為小寫字母后添加到 tmp 中。
  2. 處理空字符串情況:如果 tmp 為空字符串,根據題目定義,空字符串是回文串,直接返回 true。
  3. 回文判斷:使用雙指針法,left 指向 tmp 的開頭,right 指向 tmp 的結尾,逐個比較對應位置的字符。如果不相等,返回 false;如果都相等,最終返回 true。

復雜度分析

  • 時間復雜度:O(n)需要遍歷原字符串一次,再遍歷新字符串一次。
  • 空間復雜度:O (n),其中  n是處理后新字符串的長度。

三、解法二:直接原地篩選判斷

思路

這種方法不創(chuàng)建新的字符串,而是直接在原字符串上使用雙指針法進行篩選和判斷。通過兩個指針 left 和 right 分別從字符串的兩端開始向中間移動,跳過非字母數字字符,同時將字符轉換為小寫后進行比較。

代碼實現

#include <iostream>
#include <string>
#include <cctype>
 
class Solution {
public:
    bool isPalindrome(std::string s) //第二種方式,直接原地篩選判斷
    {
        string::iterator left = s.begin();
        string::iterator right = s.end() - 1;
 
        while (left < right)
        {
            // 跳過左邊的非字母數字字符
            while (left < right && !isalnum(*left))
            {
                ++left;
            }
            // 跳過右邊的非字母數字字符
            while (left < right && !isalnum(*right))
            {
                --right;
            }
 
            if (left < right) {
                // 將字符轉換為小寫后比較
                if (tolower(*left) != tolower(*right))
                {
                    return false;
                }
                ++left;
                --right;
            }
        }
        //跳出循環(huán),要么left==right,要么left>right 
        //說明所有需要比較的字符對都已經檢查過,且都相等
        return true;
    }
};

代碼解釋

  1. 初始化指針:使用迭代器 left 指向字符串的開頭,right 指向字符串的結尾。
  2. 跳過非字母數字字符:通過兩個內層 while 循環(huán),分別將 left 和 right 指針移動到字母數字字符的位置。
  3. 字符比較:將 left 和 right 指針指向的字符轉換為小寫后進行比較,如果不相等,返回 false;如果相等,繼續(xù)移動指針。
  4. 返回結果:當 left 大于等于 right 時,說明所有需要比較的字符對都已經檢查過,且都相等,返回 true。

復雜度分析

  • 時間復雜度:O(n),只需要遍歷一次字符串。
  • 空間復雜度:O(1),只使用了常數級的額外空間。

總結

兩種解法都能有效解決回文串判斷問題:

解法一邏輯清晰,易于理解,但需要額外的空間存儲處理后的字符串;

解法二原地操作,空間復雜度更低,更適合處理大規(guī)模數據。在實際應用中,可以根據具體需求選擇合適的解法。

以上就是C++實現回文串判斷的兩種高效方法的詳細內容,更多關于C++回文串判斷的資料請關注腳本之家其它相關文章!

相關文章

  • OpenCV實現直線擬合

    OpenCV實現直線擬合

    這篇文章主要為大家詳細介紹了OpenCV實現直線擬合,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-06-06
  • OpenCV實現車牌定位(C++)

    OpenCV實現車牌定位(C++)

    這篇文章主要為大家詳細介紹了OpenCV實現車牌定位,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-11-11
  • C++中CopyFile和MoveFile函數使用區(qū)別的示例分析

    C++中CopyFile和MoveFile函數使用區(qū)別的示例分析

    這篇文章主要介紹了C++中CopyFile和MoveFile函數使用區(qū)別的示例分析,CopyFile表示將文件A拷貝到B,如果B已經存在則覆蓋,MoveFile表示將文件A移動到。對此感興趣的可以來了解一下
    2020-07-07
  • 你不知道的C++中namespace和using的用法實例

    你不知道的C++中namespace和using的用法實例

    在C++語言編寫的程序中,變量和函數等的作用范圍是有一定限制的,下面這篇文章主要給大家介紹了一些你不知道的C++中namespace和using的用法,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考下
    2022-12-12
  • C++圖像處理之雙邊濾波

    C++圖像處理之雙邊濾波

    這篇文章主要為大家詳細介紹了C++圖像處理之雙邊濾波,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-10-10
  • C++中vector的實現方法示例詳解

    C++中vector的實現方法示例詳解

    這篇文章主要介紹了C++中vector實現的相關資料,vector是C++中重要的容器之一,底層通過三個迭代器實現,分別是_start,?_finish,?和_end_of_storage,文中通過代碼介紹的非常詳細,需要的朋友可以參考下
    2024-10-10
  • C++實現顯示MP3文件信息的方法

    C++實現顯示MP3文件信息的方法

    這篇文章主要介紹了C++實現顯示MP3文件信息的方法,可實現顯示如作者、專輯等(libZPlay)信息的功能,需要的朋友可以參考下
    2015-06-06
  • C++調用C函數報錯無法解析的外部命令/無法解析的外部符號問題

    C++調用C函數報錯無法解析的外部命令/無法解析的外部符號問題

    這篇文章主要介紹了C++調用C函數報錯無法解析的外部命令/無法解析的外部符號問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語言中位運算符"|"的5種高級用法總結

    C語言中位運算符"|"的5種高級用法總結

    這篇文章主要為大家詳細介紹了C語言中位運算符"|"的5種高級用法,文中的示例代碼講解詳細,具有一定的參考價值,需要的可以參考一下
    2023-04-04
  • C語言深入淺出講解順序表的實現

    C語言深入淺出講解順序表的實現

    線性表是最簡單的數據結構,而順序表又是最簡單的線性表,其基本思想是用一段地址連續(xù)的儲存單元依次存儲線性表的數據元素,比如我們常用的一維數組,下面代碼實現了順序表的定義以及基本操作
    2022-04-04

最新評論