力扣高频|算法面试题汇总(二):字符串

力扣高频|算法面试题汇总(一):开始之前
力扣高频|算法面试题汇总(二):字符串
力扣高频|算法面试题汇总(三):数组
力扣高频|算法面试题汇总(四):堆、栈与队列
力扣高频|算法面试题汇总(五):链表
力扣高频|算法面试题汇总(六):哈希与映射
力扣高频|算法面试题汇总(七):树
力扣高频|算法面试题汇总(八):排序与检索
力扣高频|算法面试题汇总(九):动态规划
力扣高频|算法面试题汇总(十):图论
力扣高频|算法面试题汇总(十一):数学&位运算

力扣高频|算法面试题汇总(二):字符串

力扣链接
目录:

  • 1.验证回文串
  • 2.分割回文串
  • 3.单词拆分
  • 4.单词拆分 II
  • 5.实现 Trie (前缀树)
  • 6.单词搜索 II
  • 7.有效的字母异位词
  • 8.字符串中的第一个唯一字符
  • 9.反转字符串

1.验证回文串

给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明:本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: “A man, a plan, a canal: Panama”
输出: true
示例 2:
输入: “race a car”
输出: false

思路:使用两个指针,一个从左边开始,一个从右边开始,挨着比较,需要处理的是:1.大写变小写。2. 如果不是字母或者数字,则跳过。
C++

class Solution {
   
   
public:
    bool isPalindrome(string s) {
   
   
        // 转换成小写字母
        transform(s.begin(),s.end(), s.begin(), ::tolower);
        int length = s.size();
        int i = 0;
        int j = length -1;
        while(i < j){
   
   
            // 判断是否是数字和英文字符
            if(!isalnum(s[i])){
   
   //!(s[i]<='9' && s[i] >= '0' && s[i] <= 'z' && s[i] >= 'a')
                ++i;
                continue;
            }else if(!isalnum(s[j])){
   
   
                --j;
                continue;
            }
            // 转换大小写
            char a = s[i];
            char b = s[j];
            if(a == b){
   
   
                ++i;
                --j;
            }else{
   
   
                return false;
            }
        }
        return true;
    }
};

Python

class Solution:
    def isPalindrome(self, s: str) -> bool:
        pl = 0
        pr = len(s) - 1
        while pl < pr:
            if not s[pl].isalnum():
                pl += 1
                continue
            elif not s[pr].isalnum():
                pr -= 1
                continue
            if s[pl].lower() == s[pr].lower():
                pl += 1
                pr -= 1
            else:
                return False
        return True

2.分割回文串

给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。
返回 s 所有可能的分割方案。
示例:
输入: “aab”
输出:
[
[“aa”,“b”],
[“a”,“a”,“b”]
]

参考回溯法
总结一下:

  • 1.把字符串“aab”,按长度n(n <= 字符串的长度)进行分割。
  • 2.n从1开始。
  • 3.start=0,n=1时,按顺序对字符串进行分割,首先得到”a“,判断满足回文要求,进行回溯,end=1。
  • 4.下一次开始,start=1,得到”a“,判断满足回文要求,进行回溯,end=2。
  • 5.下一次开始,start=2,得到”b“,判断满足回文要求,进行回溯,end=3。
  • 6.下一次开始,start=3,已经>=字符串的长度(3),得到分割结果,进行保存,结束回溯,return到上次回溯的的地方,即start=2,然后把res中保存的最后一个结果弹出,此时res中为[“a”, “a”],并依次回溯到start=0,end=1的地方,此时res中的元素已经全部弹出,为空。
  • 7.进行下一次for循环,end=2,即分割长度为2,依次进行判断…

C++

class Solution {
   
   
public:
    // 保存所有的分割结果:
    vector<vector<string>> split_results;
    vector<vector<string>> partition(string s) {
   
   
        if(s.size() == 0)
            return split_results;
        // 单次分割成回文串的结果
        vector<string> res;
        // 使用回溯法进行结果查找
        back(s, 0, res); // s: 完整的字符串, 0: 开始的位置, res: 单次分割的结果
        return split_results;
    }
    void back(string s, int start, vector<string> res){
   
   
        // 首先判断回溯停止条件
        if( start >= s.size()){
   
   
            // 保存单次分割结果
            split_results.push_back(res);
            return ;
        }
        for(int end = start + 1; end < s.size() + 1; ++end){
   
   
            // 截取字符串
            string split_s = s.substr(start, end - start);
            // 回文串判断
            if (isPalindrome(split_s)){
   
   
                // 添加当前符合要求的字符串
                res.push_back(split_s);
                // 回溯
                back(s, end, res); 
                // 弹出栈顶
                res.pop_back();
            }
        }
    }
    // 是否是回文串判断
    bool isPalindrome(string s){
   
   
        if(s.size() == 0)
            return false;
        int start = 0;
        int end = s.size() -1;
        while( start < end){
   
   
            if(s[start] == s[end]){
   
   
                ++start;
                --end;
            }else{
   
   
                return false;
            }
        }
        return true;
    }
    
};

Python

class Solution:
    # def partition(self, s: str) -> List[List[str]]:
    def partition(self, s):
        
        # 保存分割下来的结果
        self.split_results = []
        if len(s) == 0:
            return self.split_results
        # 单次分割的结果
        res = []
        # 回溯法进行查找
        self.back(s, 0, res) # s: 需要分割的字符串 0:起点位置  res:单次分割的结果
        return self.split_results
           
    # 回溯法
    def back(self, s, start, res):
        # 回溯的截止条件
        if start >= len(s):
            # 一次回溯结束
            # 对res进行拷贝,防止弹出时,split_results数据变化
            resCopy = res.copy()
            self.split_results.append(resCopy)
            return
        # 以start开始,截取字符串进行判断
### 前端面试常见 LeetCode 题目汇总 在前端开发领域,LeetCode 是许多求职者准备技术面试的重要资源之一。以下是常见的几类问题及其对应的经典题目: #### 一、字符串处理 字符串操作是前端开发者经常遇到的基础技能测试点。以下是一些典型的字符串相关题目: - **387. 字符串中的第一个唯一字符** [^1] 此题考察如何高效找到字符串中第一次只出现一次的字符索引。 ```javascript function firstUniqChar(s) { const map = new Map(); for (let char of s) { map.set(char, (map.get(char) || 0) + 1); } for (let i = 0; i < s.length; i++) { if (map.get(s[i]) === 1) return i; } return -1; } ``` #### 、数组与矩阵 数组和矩阵的操作也是前端工程师必备的能力之一。 - **283. 移动零** 该题要求将数组中的所有 `0` 移到末尾,同时保持其他元素相对顺序不变。 ```javascript function moveZeroes(nums) { let index = 0; for (let num of nums) { if (num !== 0) { nums[index++] = num; } } while (index < nums.length) { nums[index++] = 0; } } ``` #### 三、树结构 树形数据结构的应用广泛存在于 DOM 操作以及虚拟 DOM 的实现过程中。 - **94. 叉树的中序遍历** [^2] 通过递归或者迭代方法完成叉树的中序遍历,验证出栈顺序是否满足 D、B、E、A、C、F 要求 [^2]。 ```javascript function inorderTraversal(root) { const result = []; function traverse(node) { if (!node) return; traverse(node.left); result.push(node.val); traverse(node.right); } traverse(root); return result; } ``` #### 四、算法设计 一些综合性较强的题目能够很好地检验候选人的逻辑思维能力。 - **两数之和 II 输入有序数组** 给定一个已按照升序排列 的整数数组 numbers ,找出两个数使得它们相加之和等于目标数值 target 。返回这两个数的下标值(从 1 开始计数)。 ```javascript function twoSum(numbers, target) { let left = 0, right = numbers.length - 1; while (left < right) { const sum = numbers[left] + numbers[right]; if (sum === target) { return [left + 1, right + 1]; } else if (sum < target) { left++; } else { right--; } } } ``` 以上列举了一些高频考点,实际备考时还需要结合具体岗位需求和个人薄弱环节进行针对性练习 [^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值