当前位置: 首页 > news >正文

沈阳专业网站建设公司排名/宁波做seo推广企业

沈阳专业网站建设公司排名,宁波做seo推广企业,上海 外贸网站,济南设计开发app一、字符串处理核心知识点 1. Java 字符串特性 (1)不可变性(Immutable) 本质:String 类基于 final char[] value 实现,一经创建不可修改,任何修改操作都会生成新对象。应用场景: …

一、字符串处理核心知识点

1. Java 字符串特性

(1)不可变性(Immutable)
  • 本质String 类基于 final char[] value 实现,一经创建不可修改,任何修改操作都会生成新对象。
  • 应用场景
    • 频繁修改字符串时,使用 StringBuilder(非线程安全)或 StringBuffer(线程安全),其内部维护可变字符数组,避免频繁创建对象。
    // 反例:循环中用 + 拼接字符串(时间复杂度 O(n²))
    String s = "";
    for (int i = 0; i < n; i++) {s += i; // 每次拼接生成新字符串
    }// 正例:使用 StringBuilder(时间复杂度 O(n))
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < n; i++) {sb.append(i);
    }
    
(2)常用 API 详解
方法描述时间复杂度
charAt(int index)返回指定索引处的字符,索引范围 [0, length()-1],越界抛出异常O(1)
substring(int begin)
substring(int begin, int end)
截取子串,左闭右开区间 [begin, end),不包含 end 索引字符O(k)
toCharArray()将字符串转换为字符数组O(n)
indexOf(String str)
lastIndexOf(String str)
查找子串首次 / 末次出现的位置,未找到返回 -1O(n×m)
matches(String regex)验证字符串是否匹配正则表达式O(n)
split(String regex)根据正则表达式分割字符串,返回字符串数组O(n)

2. 高频解题技巧

技巧核心思想典型例题(难度)优化点
双指针快慢指针或左右指针,用于遍历、交换、验证回文等场景125. 验证回文串(简单)
344. 反转字符串(简单)
原地操作,空间复杂度 O (1)
滑动窗口通过维护窗口 [left, right] 动态调整区间,解决子串 / 子数组问题3. 无重复字符的最长子串(中等)
76. 最小覆盖子串(困难)
用哈希表 / 数组记录字符频率,优化窗口收缩逻辑
哈希映射(HashMap)统计字符频率、快速查找字符位置,适用于异位词、字符匹配问题387. 字符串中的第一个唯一字符(简单)
49. 字母异位词分组(中等)
用 int[128] 替代 HashMap,提升访问速度(尤其针对 ASCII 字符)
动态规划(DP)定义状态转移方程,解决最长公共子串、最长回文子串等问题5. 最长回文子串(中等)
1143. 最长公共子序列(中等)
状态压缩(如二维数组压缩为一维),降低空间复杂度
栈结构处理括号匹配、表达式求值、路径简化等具有后进先出特性的问题20. 有效的括号(简单)
71. 简化路径(中等)
用 Deque 替代 Stack,优先使用 ArrayDeque(性能更优)

二、经典题型解析(附变形题与优化思路)

1. 反转字符串(No. 344)

问题描述:原地反转字符数组,要求空间复杂度 O (1)。
双指针解法

public void reverseString(char[] s) {int left = 0, right = s.length - 1;while (left < right) {// 交换左右指针字符char temp = s[left];s[left++] = s[right];s[right--] = temp;}
}

变形题:反转字符串中的单词(No. 151)
解法思路

  1. 去除首尾空格,按多个空格分割单词;
  2. 反转单词列表,用空格拼接结果。
public String reverseWords(String s) {// 1. 去除首尾空格并按空格分割(+ 表示匹配一个或多个空格)String[] words = s.trim().split(" +");// 2. 反转单词列表Collections.reverse(Arrays.asList(words));// 3. 用空格拼接结果return String.join(" ", words);
}

优化点:避免使用 split 产生的空字符串,改用双指针手动分割单词。

2. 最长无重复子串(No. 3)

滑动窗口 + 哈希表解法

public int lengthOfLongestSubstring(String s) {Map<Character, Integer> map = new HashMap<>(); // 记录字符最后出现的位置int maxLen = 0, left = 0;for (int right = 0; right < s.length(); right++) {char c = s.charAt(right);if (map.containsKey(c)) {// 窗口左边界至少移动到重复字符的下一个位置left = Math.max(left, map.get(c) + 1);}map.put(c, right); // 更新字符位置maxLen = Math.max(maxLen, right - left + 1); // 计算当前窗口长度}return maxLen;
}

进阶优化:使用 int[128] 数组替代 HashMap(适用于 ASCII 字符集)

public int lengthOfLongestSubstring(String s) {int[] freq = new int[128]; // 初始化全为 0int maxLen = 0, left = 0;for (int right = 0; right < s.length(); right++) {char c = s.charAt(right);freq[c]++;// 窗口内出现重复字符时,收缩左边界while (freq[c] > 1) {freq[s.charAt(left++)]--;}maxLen = Math.max(maxLen, right - left + 1);}return maxLen;
}

3. 有效括号(No. 20)

栈结构解法

public boolean isValid(String s) {Deque<Character> stack = new ArrayDeque<>(); // 优先使用双端队列Map<Character, Character> map = Map.of(')', '(', ']', '[', '}', '{'); // Java 9+ 语法for (char c : s.toCharArray()) {if (!map.containsKey(c)) { // 左括号入栈stack.push(c);} else { // 右括号匹配if (stack.isEmpty() || stack.pop() != map.get(c)) {return false;}}}return stack.isEmpty(); // 最终栈为空则匹配成功
}

易错点:右括号出现时,需先判断栈是否为空,避免 NullPointerException

三、进阶算法与复杂题型

1. KMP 算法(No. 28 实现 strStr ())

核心思想:利用前缀函数(lps 数组)记录模式串的最长公共前后缀,避免重复匹配。
算法步骤

  1. 构建前缀表(lps 数组)
    lps[i] 表示模式串前 i 个字符的最长公共前后缀长度(不包含自身)。
  2. 模式匹配:通过前缀表跳过已匹配的部分,减少不必要的回溯。
public int strStr(String haystack, String needle) {int n = haystack.length(), m = needle.length();if (m == 0) return 0; // 空字符串特殊处理// 1. 构建前缀表(lps 数组)int[] lps = new int[m];for (int i = 1, len = 0; i < m;) { // i 为当前字符索引,len 为最长公共前后缀长度if (needle.charAt(i) == needle.charAt(len)) {lps[i++] = ++len; // 匹配成功,长度+1} else if (len > 0) {len = lps[len - 1]; // 回溯到上一个最长公共前后缀} else {lps[i++] = 0; // 无公共前后缀}}// 2. 模式匹配for (int i = 0, j = 0; i < n;) { // i 为主串索引,j 为模式串索引if (haystack.charAt(i) == needle.charAt(j)) {i++;j++;if (j == m) return i - m; // 匹配成功,返回起始位置} else if (j > 0) {j = lps[j - 1]; // 模式串回溯到 lps[j-1] 位置} else {i++; // 主串后移一位}}return -1; // 未找到匹配
}

时间复杂度:构建前缀表 O (m),匹配过程 O (n),总体 O (n+m)。

2. 字符串排列(No. 567 验证子串是否为排列)

滑动窗口 + 频率数组解法

public boolean checkInclusion(String s1, String s2) {int[] count = new int[26]; // 记录 s1 字符频率for (char c : s1.toCharArray()) {count[c - 'a']++;}int left = 0, right = 0, match = 0; // match 记录匹配的字符数while (right < s2.length()) {int rChar = s2.charAt(right) - 'a';if (count[rChar] > 0) { // 字符在 s1 中存在count[rChar]--;match++;right++;} else { // 字符不在 s1 中,重置窗口count[s2.charAt(left) - 'a']++; // 左边界字符放回频率数组if (match > 0 && s2.charAt(left) - 'a' == rChar) { // 若移除的是不匹配字符,重置 matchmatch = 0;}left++;right = left; // 右边界回到左边界,重新开始匹配}if (match == s1.length()) { // 窗口内所有字符匹配 s1return true;}}return false;
}

优化点:通过 match 变量记录匹配进度,避免每次比较整个窗口的频率数组。

四、常见易错点与避坑指南

易错点示例代码(反例)修正方法
索引越界char c = s.charAt(s.length());先判断 s.length() > 0,或使用 try-catch 捕获异常
字符串比较误区if (s1 == s2)(比较引用而非内容)使用 s1.equals(s2),或对可能为 null 的对象用 Objects.equals(s1, s2)
不可变陷阱for (int i=0; i<n; i++) s += i;(低效拼接)改用 StringBuilder.append()
字符与数字转换int num = 'a' - 'A';(正确,得 32)
int digit = s.charAt(i) - '0'(需确保字符是数字)
转换前用 Character.isDigit(c) 验证,避免非法字符导致错误
边界条件遗漏空字符串 ""、全空格 " "、超长整数 "2147483648"(超出 Integer 范围)测试用例中必须包含空输入、极端值,处理大数时用 long 过渡并判断溢出
正则表达式转义s.split(".")(无法分割,. 是正则通配符)转义为 s.split("\\."),或使用 Pattern.quote(".")

五、系统化刷题策略

1. 分阶段训练路线

阶段目标推荐题型(题号 / 难度)学习要点
基础掌握字符串特性与基础 API344. 反转字符串(简单)
20. 有效括号(简单)
双指针、栈的基本使用
进阶熟练运用滑动窗口、哈希表3. 无重复字符的最长子串(中等)
49. 字母异位词分组(中等)
窗口收缩逻辑、字符频率统计
高阶动态规划、KMP 等复杂算法5. 最长回文子串(中等)
28. 实现 strStr ()(中等)
状态转移方程设计、前缀函数理解
挑战综合应用与优化76. 最小覆盖子串(困难)
567. 字符串排列(中等)
多技巧结合、性能优化(如用数组替代哈希表)

2. 测试用例设计模板

// 以反转字符串为例
public class TestReverseString {@Testpublic void testCases() {// 1. 空输入char[] s1 = {};reverseString(s1);assertArrayEquals(new char[]{}, s1);// 2. 单字符char[] s2 = {'a'};reverseString(s2);assertArrayEquals(new char[]{'a'}, s2);// 3. 偶数长度char[] s3 = {'h', 'e', 'l', 'l', 'o'};reverseString(s3);assertArrayEquals(new char[]{'o', 'l', 'l', 'e', 'h'}, s3);// 4. 奇数长度char[] s4 = {'A', ' ', 'm', 'a', 'n'};reverseString(s4);assertArrayEquals(new char[]{'n', 'a', 'm', ' ', 'A'}, s4);}
}

3. 代码模板总结

(1)双指针模板(反转 / 回文)
public void twoPointersTemplate(char[] s) {int left = 0, right = s.length - 1;while (left < right) {// 交换/比较操作char temp = s[left];s[left++] = s[right];s[right--] = temp;}
}
(2)滑动窗口模板(子串问题)
public int slidingWindowTemplate(String s) {int[] freq = new int[128];int left = 0, maxLen = 0;for (int right = 0; right < s.length(); right++) {char c = s.charAt(right);freq[c]++;// 窗口收缩条件(根据题意调整)while (freq[c] > 1) {freq[s.charAt(left++)]--;}maxLen = Math.max(maxLen, right - left + 1);}return maxLen;
}

通过系统掌握字符串处理的核心技巧,配合合理的Java API使用,能够显著提升解决LeetCode字符串类题目的效率。建议从简单题开始建立信心,逐步挑战中等难度综合题,最后攻克KMP等高级算法难题。

http://www.whsansanxincailiao.cn/news/32040012.html

相关文章:

  • 湖南怀化/北京中文seo
  • 上海建设摩托车官网报价/百度免费优化
  • 网站之间如何做视频交换/关键词优化方法有什么步骤
  • 广州网站建设定制价格/seo网站优化案例
  • 柳州网站建设公司/关键词优化的策略
  • 昆明做网站公司/国际新闻最新消息今天军事新闻
  • 如何增加网站关键词库/优化人员是什么意思
  • 休闲游戏开发/搜外seo
  • 雅安市政建设公司网站/如何网络推广新产品
  • 做网站费用走什么科目/代运营哪家比较可靠
  • 刚做优化的网站什么能更新/公众号怎么推广和引流
  • 南宁做网站推广nnsom/提升网页优化排名
  • 网站首页banner/网络营销的未来发展趋势论文
  • 移动网站开发测试工具/软文推广公司有哪些
  • 古镇营销型网站建设/优化方案怎么写
  • 上海商务网站建设/公司地址怎么弄在百度上显示
  • 家用100mb光纤做网站/windows优化大师提供的
  • 网站为何突然不收录了/关键词优化顾问
  • 心悦会员荣誉战场两张免做卡网站/定制网站+域名+企业邮箱
  • 雄安网站建设推广/自己建网站要花多少钱
  • 厦门网站建设是什么意思/下载地图导航手机版免流量费用
  • wordpress 搜索小工具栏/优化游戏性能的软件
  • 如何在网站找做贸易的客户/客源引流推广
  • 网站提交链接入口/宁波seo推广优化哪家强
  • 做网站参考文献/手机seo排名
  • 运城网站建设公司有多少/百度网盘人工客服
  • wordpress 百万ip/seo关键词推广多少钱
  • 北京网站备案拍照的地点/链接检测工具
  • 个人备案 网站内容/关键词在线采集
  • 聊城做网站建设/网络营销推广方案范文