【代码随想录】字符串刷题

2023-10-27


关于字符串类的题目,要不要使用库函数呢?

如果使用库函数可以直接做出来,建议不要使用库函数。
如果库函数只是题目的一部分,可以考虑使用库函数。

反转字符串

题目:344. 反转字符串 - 力扣(LeetCode)

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。

输入:s = ["h","e","l","l","o"]
输出:["o","l","l","e","h"]

使用位运算进行交换操作:

public void reverseString(char[] s) {
	int size = s.length - 1;
	for (int i = 0; i < s.length / 2; i++) {
		int j = size - i;
		s[i] ^= s[j];
		s[j] ^= s[i];
		s[i] ^= s[j];
	}
}

一般可以将 反转字符数组 抽取成模板(经常会用到这个函数)

class Solution {
    public void reverseString(char[] s) {
        reverse(s, 0, s.length - 1);
    }
	// 反转字符数组
    void reverse(char[] cs, int l, int r) {
        while (l < r) {
            cs[l] ^= cs[r];
            cs[r] ^= cs[l];
            cs[l++] ^= cs[r--];
        }
    }
}

反转字符串II

题目:541. 反转字符串 II - 力扣(LeetCode)

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。

  • 如果剩余字符少于 k 个,则将剩余字符全部反转。
  • 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。
输入:s = "abcdefg", k = 2
输出:"bacdfeg"
class Solution {
    public String reverseStr(String s, int k) {
        char[] cs = s.toCharArray();
        int len = cs.length;
        for (int i = 0; i < len; i += (k * 2)) {
            // 如果剩余字符少于 k 个,则将剩余字符全部反转
            if (len - i < k) reverse(cs, i, len - 1);
            // 如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样
            // else if (len - i < k * 2) reverse(cs, i, i + k - 1); // 可省略
            // 每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符
            else reverse(cs, i, i + k - 1); 
        }
        return new String(cs);
    }

    void reverse(char[] cs, int i, int j) {
        while (i < j) {
            cs[i] ^= cs[j];
            cs[j] ^= cs[i];
            cs[i++] ^= cs[j--];
        }
    }
}

替换空格

题目:剑指 Offer 05. 替换空格 - 力扣(LeetCode)

请实现一个函数,把字符串 s 中的每个空格替换成"%20"。

输入:s = "We are happy."
输出:"We%20are%20happy."
public String replaceSpace(String s) {
	StringBuilder sb = new StringBuilder();
	for (char c : s.toCharArray()) {
		if (c != ' ') sb.append(c);
		else sb.append("%20");
	}
	return sb.toString();
}

反转字符串中的单词**

题目:151. 反转字符串中的单词 - 力扣(LeetCode)

给你一个字符串 s ,请你反转字符串中 单词 的顺序。

单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。

返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。

注意:输入字符串 s 中可能会存在前导空格、尾随空格或者单词间的多个空格。返回的结果字符串中,单词间应当仅用单个空格分隔,且不包含任何额外的空格。

输入:s = "the sky is blue"
输出:"blue is sky the"

不使用内置 API:

  1. 去除首尾以及中间多余空格
  2. 反转整个字符串
  3. 反转各个单词
class Solution {
    public String reverseWords(String s) {
        // 1. 去除首尾以及中间多余空格
        StringBuilder sb = removeSpace(s);
        // 2. 反转整个字符串
        reverseString(sb, 0, sb.length() - 1);
        // 3. 反转各个单词
        reverseEachWord(sb);
        return sb.toString();
    }

    // 去除首尾及中间多余空格
    StringBuilder removeSpace(String s) {
        int i = 0, j = s.length() - 1;
        while (s.charAt(i) == ' ') i++; // 去除首空格
        while (s.charAt(j) == ' ') j--; // 去除尾空格
        // 去除中间多余空格
        StringBuilder sb = new StringBuilder();
        while (i <= j) {
            char c = s.charAt(i);
            if (c != ' ' || sb.charAt(sb.length() - 1) != ' ')
                sb.append(c);
            i++;
        }
        return sb;
    }

    // 翻转字符串
    void reverseString(StringBuilder sb, int i, int j) {
        while (i < j) {
            char tmp = sb.charAt(i);
            sb.setCharAt(i++, sb.charAt(j));
            sb.setCharAt(j--, tmp);
        }
    }

    // 翻转每个单词
    void reverseEachWord(StringBuilder sb) {
        int i = 0, j = 1, n = sb.length();
        while (i < n) {
            // 找到单词末尾
            while (j < n && sb.charAt(j) != ' ') j++;
            // 翻转单词
            reverseString(sb, i, j - 1);
            // 更新位置,去找下一个单词
            i = j + 1;
            j = i + 1;
        }
    }
}

使用 split 函数:

class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = new StringBuilder();
        String[] ss = s.split("\\s+");
        for (int i = ss.length - 1; i >= 0; i--) sb.append(ss[i] + " ");
        return sb.toString().trim();
    }
}

从后往前遍历,每次找到单词后添加:使用了字符串 API

class Solution {
    public String reverseWords(String s) {
        StringBuilder sb = new StringBuilder();
        int i = s.length() - 1, j = i;
        while (i >= 0) {
            while (i >= 0 && s.charAt(i) != ' ') i--;
            sb.append(s.substring(i + 1, j + 1) + " ");
            while (i >= 0 && s.charAt(i) == ' ') i--;
            j = i;
        }
        return sb.toString().trim();
    }
}

左旋转字符串

题目:剑指 Offer 58 - II. 左旋转字符串 - 力扣(LeetCode)

字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。请定义一个函数实现字符串左旋转操作的功能。比如,输入字符串"abcdefg"和数字2,该函数将返回左旋转两位得到的结果"cdefgab"。

输入: s = "abcdefg", k = 2
输出: "cdefgab"

利用 substring 函数:(左开右闭)

public String reverseLeftWords(String s, int n) {
	return s.substring(n) + s.substring(0, 2);
}

char[] 反转 3 次:

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] cs = s.toCharArray();
        int len = s.length();
        reverse(cs, 0, n - 1);
        reverse(cs, n, len - 1);
        reverse(cs, 0, len - 1);
        return new String(cs);
    }
    void reverse(char[] cs, int i, int j) {
        while (i < j) {
            cs[i] ^= cs[j];
            cs[j] ^= cs[i];
            cs[i++] ^= cs[j--];
        }
    }
}

利用 StringBuilder 拼接:

class Solution {
    public String reverseLeftWords(String s, int n) {
        char[] cs = s.toCharArray();
        StringBuilder sb = new StringBuilder();
        for (int i = n; i < cs.length; i++) sb.append(cs[i]);
        for (int i = 0; i < n; i++) sb.append(cs[i]);
        return sb.toString();
    }
}

实现 strStr()*

题目:28. 实现 strStr() - 力扣(LeetCode)

给你两个字符串 haystack 和 needle ,请你在 haystack 字符串中找出 needle 字符串出现的第一个位置(下标从 0 开始)。如果不存在,则返回  -1 。

输入:haystack = "hello", needle = "ll"
输出:2

这题最优解是 KMP,以后学习后再刷!

利用 indexOf 函数:

public int strStr(String haystack, String needle) {
	return haystack.indexOf(needle);
}

双指针:

public int strStr(String s1, String s2) {
	if (s2 == "" || s1.equals(s2)) return 0;
	int l1 = s1.length(), l2 = s2.length();
	if (l1 < l2) return -1;

	char c1 = s2.charAt(0); // s2 的首字符
	for (int i = 0; i < l1 - l2 + 1; i++) {
		// 在 s1 中找 s2 的首字符
		if (s1.charAt(i) == c1) {
			// 开始逐位比较 s1 和 s2
			int j = 0;
			while (s1.charAt(i + j) == s2.charAt(j)) {
				j++;
				// 连续 l2 个长度的字符相同, 说明 s1 中包含 s2
				if (j == l2) return i;
			}
		}
	}
	return -1;
}

滑动窗口:

public int strStr(String s1, String s2) {
	if (s2 == "" || s1.equals(s2)) return 0;
	int l1 = s1.length(), l2 = s2.length();
	if (l1 < l2) return -1;
	
	char c1 = s2.charAt(0); // s2 首字符
	for (int i = 0; i < l1 - l2 + 1; i++) 
		if (s1.charAt(i) == c1 && s2.equals(s1.substring(i, i + l2))) 
			return i;
	return -1;
}

重复的子字符串

题目:459. 重复的子字符串 - 力扣(LeetCode)

给定一个非空的字符串 s ,检查是否可以通过由它的一个子串重复多次构成。

输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。

暴力 + 剪枝:

public boolean repeatedSubstringPattern(String s) {
	int len = s.length();
	for (int i = 1; i <= (len >> 1); i++) {
		// 字符串的长度不是串的整数倍, 必然不满足条件
		if (len % i != 0) continue;
		String sub = s.substring(0, i); // 枚举子串
		// 字符串不以该子串结尾, 必然不满足条件
		if (!sub.equals(s.substring(len - i))) continue; 
		if (sub.repeat(len / i).equals(s)) return true;
	}    
	return false;
}

去头去尾:

public boolean repeatedSubstringPattern(String s) {
	String ss = s + s;
	return ss.substring(1, ss.length() - 1).contains(s);
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【代码随想录】字符串刷题 的相关文章

随机推荐

  • Docker镜像保存为文件及从本地文件导入镜像的方法

    1 概述 我们制作好镜像后 有时需要将镜像复制到另一台服务器使用 能达到以上目的有两种方式 一种是上传镜像到仓库中 本地或公共仓库 但是另一台服务器很肯能只是与当前服务器局域网想通而没有公网的 所以如果使用仓库的方式 只能自己搭建私有仓库
  • Linux:监控GPU状态【nvidia-smi】【watch -n 1 nvidia-smi】【pip install gpustat;gpustat -i】

    一台服务器毕竟很多人都在用 这个时候查看GPU状态显得尤为重要 查看剩余显存大小 以便自己能否使用这块卡 后来查找发现有2种方式 最开始我用的就是第一种 但是显然不是很好用 最后发现gpustat超级好用 下面分别介绍两种用法 一 nvid
  • HAL-STM32-USB内部Flash虚拟U盘更新程序

    1 IAP部分 添加fat32文件 修改Flash擦除代码 F401ccu6按扇区删除 F103按页删除 static bool fat32 write firmware const uint8 t b uint32 t addr bool
  • 如何练成大力金刚指:IKBC - C104 白色黑轴机械键盘 体验测评

    0 写在前面的话 首先 感谢张大妈对我的信任 让我参与这次IKBC C104键盘的众测 作为一个码农 每天至少一半以上的时间在使用键盘 一把趁手的键盘 就像一个武林高手手中的绝世神兵 摧枯拉朽 无往而不利 所以 我有很多把绝世神兵 然并卵
  • python运算符——比较运算符

    在编程的世界里 是一个特殊的运算符 是为赋值运算符 是为比较运算符 a b 10 20 print a gt b吗 a gt b False print a
  • 4大主流小程序平台介绍及其优缺点对比

    文章目录 人工智能福利文章 微信小程序 优点 缺点 支付宝小程序 优点 缺点 百度小程序 优点 缺点 字节小程序 优点 缺点 总结 脑筋急转弯小程序抢先体验 程序员专属工具箱 请添加图片描述 创作者 全栈弄潮儿 个人主页 全栈弄潮儿的个人主
  • 聊聊自动化测试框架

    无论是在自动化测试实践 还是日常交流中 经常听到一个词 框架 之前学习自动化测试的过程中 一直对 框架 这个词知其然不知其所以然 最近看了很多自动化相关的资料 加上自己的一些实践 算是对 框架 有了一些理解 这篇博客 就聊聊自动化框架的一些
  • DSPTMS320F28335笔记——ADC的概念学习

    注 本文章只记录自己学习 参考多个博主和学习视频 最后附上参考的出处 本人能力有限 如果发现错误 还请多多指教 一 ADC转换步骤 A D转换器 ADC 将模拟量转换为数字量通常要经过4个步骤 1 采样 将一个时间上连续变化的模拟量转化为时
  • jupyter notebook 主题

    一 安装jupyter 主题 pip install upgrade jupyterthemes 二 jt l jt l 现在可以选择一个主题名执行以下代码换皮肤了 例如 jt t chesterish T N 这就表示选择了chester
  • PCA(主成分分析)降维可视化Matlab实现

    实现一个动态展示二维到一维的实例 以及通过使用PCA对其进行简单降维 1 二维数据降维动态演示 下图通过使用投影关系将二维点集映射到一维直线上 直观上展示了二维到一维的降维和数据的映射关系 下图使用含有噪声圆的降维 可用于讲解kernel
  • 这二维码也太美了吧!利用AI绘画[Stable Diffusion的 ControlNet]生成爆火的艺术风格二维码

    文章目录 引子 爆火的艺术二维码 这种艺术二维码是如何制作出来的 ControlNet 介绍 ControlNet的限制条件 边缘检测示例 人体姿态检测示例 使用Canny边缘检测和Openpose有什么区别 安装稳定扩散控制网Contro
  • 服务器在使用过程中如何保护数据

    在租用服务器搭建网站运营的时候 除了保证网站的正常运营之外 对于网站数据安全的保护也不容忽视 那么租用服务器的 时候如何做好防御呢 租用服务器建站的时候如何做好数据库的安全工作呢 数据库的备份工作 对于数据库备份主要分为以下几种 完全备份
  • 【GAN 01】初识GAN

    本文是对http www seeprettyface com research notes html的学习笔记 评价指标 Inception Score评价图片质量 真实图片是233分 越高越好 FID反应生成图片的多样性 越低越好 一 初
  • 【第36篇】SwinIR(超分)

    文章目录 摘要 一 简介 二 相关工作 2 1 图像恢复 2 2 视觉转换器 三 方法 3 1 网络架构 3 2 剩余旋转变压器块 四 实验 4 1 实验设置 4 2 消融研究与讨论 4 3 图像 SR 的结果 4 4 JPEG 压缩伪影减
  • spring mvc:注解@ModelAttribute妙用

    在Spring mvc中 注解 ModelAttribute是一个非常常用的注解 其功能主要在两方面 运用在参数上 会将客户端传递过来的参数按名称注入到指定对象中 并且会将这个对象自动加入ModelMap中 便于View层使用 br gt
  • C语言 - AES软件加解密算法

    概述 AES RIJNDAEL算法是一个数据块长度盒密钥长度都可变的分组加密算法 其数据块长度和密钥长度都可独立地选定为大于等于128位且小于等于256位的32位任意倍数 深入学习请参考 密码学 书籍 谢谢各位参阅 验证环境 STM32F4
  • matlab怎么看输出电压纹波,Boost变换器的能量传输模式和输出纹波电压分析.pdf

    第26卷第5期 中国电机工程学报 01 26No 5Mar 2006 2006年3月 oftheCSEE 2006Chin Soc for Proceedings Elec Eng 文章编号 0258 8013 2006 05 0119 0
  • 在 Windows 下安装 COCO API(pycocotools)

    本内容将介绍在 Windows 下安装 COCO API pycocotools 本来 COCO 对 Windows 是不支持的 不过为了支持 Windows 有人对 COCO 做了一些修改 下面是 COCO 在 GitHub 上源码地址信
  • Echarts 大数据可视化实现

    全国空气质量AQI PM2 5数据可视化源码 1 编程环境为anaconda Jupyter 以下源码已划分好 如使用Jupyter环境编写 请按照顺序写在不同代码块中 注意 若将程序写在一个代码块中 将无法运行 2 源码代码注释的部分为单
  • 【代码随想录】字符串刷题

    字符串刷题 反转字符串 反转字符串II 替换空格 反转字符串中的单词 左旋转字符串 实现 strStr 重复的子字符串 关于字符串类的题目 要不要使用库函数呢 如果使用库函数可以直接做出来 建议不要使用库函数 如果库函数只是题目的一部分 可