14.面试算法-字符串常见算法题(三)

1. 字符串回文问题

1.1 LeetCode.125. 验证回文串

回文问题在链表中是重点,在字符串中同样是个重点。当初我去美团面试第一轮技术面的第一个算法题就是让写判断字符串回文的问题。

这个本身还是比较简单的,只要先转换成字符数组,然后使用双指针方法从两头到中间比较就行了。也许是过于简单了吧,面试时经常被加餐,例如LeetCode里的两道题。 一个是普通的验证回文串,第二个是找最长的子回文串。第二个问题需要动态规划等技术,有点难度,如果感兴趣可以自行去了解下,这里先看一下基本的。

题目:

如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个回文串。

字母和数字都属于字母数字字符。

给你一个字符串 s,如果它是回文串 ,返回 true ;否则,返回 false 。

示例1:
输入 : “A man, a plan, a canal: Panama” 输出 : true
解释: “amanaplanacanalpanama” 是回文串
示例2:
输入 : “race a car” 输出 : false
解释: “raceacar” 不是回文串
示例 3:
输入:s = " "
输出:true
解释:在移除非字母数字字符之后,s 是一个空字符串 “” 。
由于空字符串正着反着读都一样,所以是回文串。

分析

最简单的方法是对字符串 s 进行一次遍历,并将其中的字母和数字字符进行保留,放在另一个字符串 sgood 中。这样我们只需要判断 sgood 是否是一个普通的回文串即可。

判断的方法有两种。第一种是使用语言中的字符串翻转 API 得到 sgood 的逆序字符串 sgood_rev,只要这两个字符串相同,那么 sgood 就是回文串。

class Solution {public boolean isPalindrome(String s) {StringBuffer sgood = new StringBuffer();int length = s.length();for (int i = 0; i < length; i++) {char ch = s.charAt(i);if (Character.isLetterOrDigit(ch)) {sgood.append(Character.toLowerCase(ch));}}StringBuffer sgood_rev = new StringBuffer(sgood).reverse();return sgood.toString().equals(sgood_rev.toString());}
}

第二种是使用双指针。初始时,左右指针分别指向 sgood 的两侧,随后我们不断地将这两个指针相向移动,每次移动一步,并判断这两个指针指向的字符是否相同。当这两个指针相遇时,就说明 sgood 时回文串。

class Solution {public boolean isPalindrome(String s) {StringBuffer sgood = new StringBuffer();int length = s.length();for (int i = 0; i < length; i++) {char ch = s.charAt(i);if (Character.isLetterOrDigit(ch)) {sgood.append(Character.toLowerCase(ch));}}int n = sgood.length();int left = 0, right = n - 1;while (left < right) {if (Character.toLowerCase(sgood.charAt(left)) != Character.toLowerCase(sgood.charAt(right))) {return false;}++left;--right;}return true;}
}

2. 字符串简单搜索问题

我们为什么叫简单搜索问题呢?因为字符串的有些搜索问题非常复杂,需要dp或者更高级的算法,例如字符匹配等等,因此这里我们先看几个简单的情况。

2.1 LeetCode387. 字符串中的第一个唯一字符

给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1。

示例 1:
输入: s = “leetcode”
输出: 0
示例 2:
输入: s = “loveleetcode”
输出: 2
示例 3:
输入: s = “aabb”
输出: -1

提示:s 只包含小写字母

我们可以对字符串进行两次遍历,在第一次遍历时,我们使用哈希映射统计出字符串中每个字符出现的次数。在第二次遍历时,我们只要遍历到了一个只出现一次的字符,那么就返回它的索引,否则在遍历结束后返回 -1。

class Solution {public int firstUniqChar(String s) {Map<Character, Integer> frequency = new HashMap<Character, Integer>();for (int i = 0; i < s.length(); ++i) {char ch = s.charAt(i);frequency.put(ch, frequency.getOrDefault(ch, 0) + 1);}for (int i = 0; i < s.length(); ++i) {if (frequency.get(s.charAt(i)) == 1) {return i;}}return -1;}
}

2.2 LeetCode58. 最后一个单词的长度

给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。

示例 1:
输入:s = “Hello World”
输出:5
解释:最后一个单词是“World”,长度为 5。
示例 2:
输入:s = " fly me to the moon "
输出:4
解释:最后一个单词是“moon”,长度为 4。
示例 3:
输入:s = “luffy is still joyboy”
输出:6
解释:最后一个单词是长度为 6 的“joyboy”。

分析
这个题还是比较简单的,反向遍历。题目要求得到字符串中最后一个单词的长度,可以反向遍历字符串,寻找最后 一个单词并计算其长度。

由于字符串中至少存在一个单词,因此字符串中一定有字母。首先找到字符串中的最后一个字母,该字母即为最后一个单词的最后一个字母。

从最后一个字母开始继续反向遍历字符串,直到遇到空格或者到达字符串的起始位置。遍历到的每个字母都是最后一个单词中的字母,因此遍历到的字母数量即为最后一个单词的长度。

class Solution {public int lengthOfLastWord(String s) {int index = s.length() - 1;while (s.charAt(index) == ' ') {index--;}int wordLength = 0;while (index >= 0 && s.charAt(index) != ' ') {wordLength++;index--;}return wordLength;}
}

3. 旋转和重排

3.1 [剑指Offer】 58. 左旋转字符串

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

示例1:
输入 : s = “abcdefg”, k = 2
输出 : “cdefgab”
示例2:
输入 : s = “lrloseumgh”, k = 6
输出 : “umghlrlose”

本题有多种方式处理的,最直观的方式是前面剪贴下来的若干字符和后面的字符保存到两个数组里,然后再按照要求合并就行了。这个在go、JavaScript 、python等语言中有切片的操作,可以非常方便地处理,java中虽然没有切片,但是可以通过子串来实现相同的功能。

class Solution {public String reverseLeftWords(String s, int n) { if (s == null || s.length() == 0) {return s;}return s.substring(n, s.length()) + s.substring(0, n);}
}

第二种方式是通过StringBuilder来实现拼接,先将第k个之后的元素添加进来,然后再将前k个添加进来,代码如下:

class Solution {public String reverseLeftWords(String s, int n) { if (s == null || s.length() == 0) {return s;}StringBuilder res = new StringBuilder();for(int i = n; i < s.length(); i++)res.append(s.charAt(i));for(int i = 0; i < n; i++)res.append(s.charAt(i));return res.toString();}
}

很明显上面两个都需要记住StringBuilder等的用法,如果使用最简单的String和char数组来处理怎么做呢?前面我们已经介绍过,所以这里只要看一下就明确了:

class Solution {public String reverseLeftWords(String s, int n) { if (s == null || s.length() == 0) {return s;}String res = "";for(int i = n; i < s.length(); i++)res += s.charAt(i);for(int i = 0; i < n; i++)res += s.charAt(i);return res;}
}

3.2 判定是否互为字符重排

给定两个字符串 s1s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例1:
输入 : s1 = “abcadfhg”, s2 = “bcafdagh” ’
输出 : true
示例2:
输入 : s1 = “abc”, s2 = “bad”
输出 : false

这个题第一眼看,感觉是个排列组合的题目,然后如果使用排列的算法来处理,难度会非常大,而且效果还不一定好。用简单的方式就能解决。

第一种方法:将两个字符串全部从小到大或者从大到小排列,然后再逐个位置比较,这时候不管两个原始字符串是什么,都可以判断出来。

代码也不复杂:

public boolean checkPermutation(String s1, String s2) { // 将字符串转换成字符数组char[] s1Chars = s1.toCharArray(); char[] s2Chars = s2.toCharArray();// 对字符数组进行排序Arrays.sort(s1Chars); Arrays.sort(s2Chars);// 再将字符数组转换成字符串,比较是否相等return new String(s1Chars).equals(new String(s2Chars));
}

注意这里我们使用了Arrays.sort(),你是否记得我们在数组一章提到过这个方法必须牢记。

第二种方法:使用Hash,注意这里我们不能简单的存是否已经存在,因为字符可能在某个串里重复存在例如"abac"。我们可以记录出现的次数,如果一个字符串经过重新排列后,能够变成另外一个字符串,那么它们的每个不同字符的出现次数是相同的。如果出现次数不同,那么表示两个字符串不能够经过重新排列得到。

这个代码逻辑不复杂,但是写起来稍微长一点:

class Solution {public boolean checkPermutation(String s1, String s2) {if (s1.length() != s2.length()) {return false;}char[] s1Chars = s1.toCharArray();Map<Character, Integer> s1Map = getMap(s1);Map<Character, Integer> s2Map = getMap(s2);for (char s1Char : s1Chars) {if (!s2Map.containsKey(s1Char) || s2Map.get(s1Char) != s1Map.get(s1Char)) {return false;}}return true;}// 统计指定字符串str中各字符的出现次数,并以Map的形式返回private Map<Character, Integer> getMap(String str) {Map<Character, Integer> map = new HashMap<>();char[] chars = str.toCharArray();for (char aChar : chars) {map.put(aChar, map.getOrDefault(aChar, 0) + 1);}return map;}
}

拓展

这个题还有一种方法,就是不管原始字符串有多长,是什么,基本元素都是26个英文字母,只少不多,那么我们可以换个思维:为两个字符串分别建立两个大小为26的字母表数组,每个位置是对应的字母出现的次数。最后统计一下两个数组的字母数和每个字母出现的次数就可以了。

这种方法其实也是文本搜索引擎的基本思想,例如 elasticSearch等,在文本搜索里有个专门的名字,叫“倒排索引”。看一下实现代码:

public class Solution {public boolean CheckPermutation(String s1, String s2) {if (s1.length() != s2.length()) {return false;}int[] c1 = count(s1);int[] c2 = count(s2);for (int i = 0; i < c1.length; i++) {if (c1[i] != c2[i]) {return false;}}return true;}private int[] count(String str) {int[] c = new int[26];char[] chars = str.toCharArray();for (char aChar : chars) {c[aChar - 'a']++;}return c;}
}

4. 最长公共前缀

这是一道经典的字符串问题,先看题目要求:

编写一个函数来查找字符串数组中的最长公共前缀。如果不存在公共前缀,返回空字符串 “”。

示例1:
输入:strs = [“flower”,“flow”,“flight”]
输出: “fl”
示例2:
输入:strs = [“dog”,“racecar”,“car”]
输出: “”
解释:输入不存在公共前缀。

要解答这个问题,我们需要先看一下公共前缀的分布有什么特点,如下图:
在这里插入图片描述
可以看到,第一种方式,我们可以竖着比较,如左图所示,每前进一个位置就比较各个串,看是不是都是相等的,只要在某一轮遇到一个不相等的,那么就结束。

第二种方式,还可以横着比较,先比较前两个找到公共前缀fix1,然后再和第三个比较公共前缀得到fix2,我们可以确定fix2一定不会比fix1更长,然后和第四个比较,得到fix4,一直到最后一个fixn。每次得到的fix都不会比前面的长,最后比较完了还剩下的就是需要找的前缀了。

看到这里你是否有种似曾相识的感觉,我们前面合并K个数组或者K个链表不也是类似的思路吗?是的,就是类似的思路。

第三种方式,我们是否可以对第二种进行优化一下,借鉴归并的思想,先两两一组找fix,然后将找到的fix再两两归并呢?当然可以了,这就是归并的方式。

先看第一种的实现方法,竖着比较。纵向扫描时,从前往后遍历所有字符串的每一列,比较相同列上的字符是否相同,如果相同则继续对下一列进行比较,如果不相同则当前列不再属于公共前缀,当前列之前的部分为最长公共前缀。

class Solution {public String longestCommonPrefix(String[] strs) { if (strs == null || strs.length == 0) {return "";}int length = strs[0].length();int count = strs.length;for (int i = 0; i < length; i++) {char c = strs[0].charAt(i);for (int j = 1; j < count; j++) {if (i == strs[j].length() || strs[j].charAt(i) != c) {return strs[0].substring(0, i);}}}return strs[0];}
}

第二种是横着依次比较,依次遍历字符串数组中的每个字符串,对于每个遍历到的字符串,更新最长公共前缀(其实就是看是否要缩短,一定不会变长),当遍历完所有的字符串以后,即可得到字符串数组中的最长公共前缀。

如果在尚未遍历完所有的字符串时,最长公共前缀已经是空串,则最长公共前缀一定是空串,因此不需要继续遍历剩下的字符串,直接返回空串即可。

class Solution {public String longestCommonPrefix(String[] strs) { if (strs == null || strs.length == 0) {return "";}String prefix = strs[0];int count = strs.length;for (int i = 1; i < count; i++) {prefix = longestCommonPrefix(prefix, strs[i]);if (prefix.length() == 0) {break;}}return prefix;}public String longestCommonPrefix(String str1, String str2) {int length = Math.min(str1.length(), str2.length());int index = 0;while (index < length && str1.charAt(index) == str2.charAt(index)) {index++;}return str1.substring(0, index);}
}

再看第三种,归并方法,这种方式也可以叫分治,就是先两两判断,之后再两两比较,直到得到最终的结果。

class Solution {public String longestCommonPrefix(String[] strs) { if (strs == null || strs.length == 0) {return "";} else {return longestCommonPrefix(strs, 0, strs.length - 1);}}public String longestCommonPrefix(String[] strs, int start, int end) {if (start == end) {return strs[start];} else {int mid = (end - start) / 2 + start;String lcpLeft = longestCommonPrefix(strs, start, mid);String lcpRight = longestCommonPrefix(strs, mid + 1, end);return commonPrefix(lcpLeft, lcpRight);}}public String commonPrefix(String lcpLeft, String lcpRight) {int minLength = Math.min(lcpLeft.length(), lcpRight.length());for (int i = 0; i < minLength; i++) {if (lcpLeft.charAt(i) != lcpRight.charAt(i)) {return lcpLeft.substring(0, i);}}return lcpLeft.substring(0, minLength);}
}

5. 字符串压缩问题

这个题也是出现频率很高的题目,经常在面经中看到。实现起来略有难度,我们一起看一下。

题目要求

给你一个字符数组 chars ,请使用下述算法压缩:

从一个空字符串 s 开始。对于 chars 中的每组 连续重复字符 :

如果这一组长度为 1 ,则将字符追加到 s 中。
否则,需要向 s 追加字符,后跟这一组的长度。
压缩后得到的字符串 s 不应该直接返回 ,需要转储到字符数组 chars 中。需要注意的是,如果组长度为 10 或 10 以上,则在 chars 数组中会被拆分为多个字符。

请在修改完输入数组后 ,返回该数组的新长度。

你必须设计并实现一个只使用常量额外空间的算法来解决此问题。

示例 1:
输入:chars = [“a”,“a”,“b”,“b”,“c”,“c”,“c”]
输出:返回 6 ,输入数组的前 6 个字符应该是:[“a”,“2”,“b”,“2”,“c”,“3”]
解释:“aa” 被 “a2” 替代。“bb” 被 “b2” 替代。“ccc” 被 “c3” 替代。
示例 2:
输入:chars = [“a”]
输出:返回 1 ,输入数组的前 1 个字符应该是:[“a”]
解释:唯一的组是“a”,它保持未压缩,因为它是一个字符。
示例 3:
输入:chars = [“a”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”,“b”]
输出:返回 4 ,输入数组的前 4 个字符应该是:[“a”,“b”,“1”,“2”]。
解释:由于字符 “a” 不重复,所以不会被压缩。“bbbbbbbbbbbb” 被 “b12” 替代。

这个题貌似采用双指针策略来处理就行,但是再分析发现三个指针才够。

我们可以使用两个指针分别标志我们在字符串中读和写的位置,还要一个指针left用来标记重复字段的开始位置。read指针不断向前读取,每次当读指针read 移动到某一段连续相同子串的最右侧,我们就在写指针 write 处依次写入该子串对应的字符和子串长度即可。

当读指针read位于字符串的末尾,或读指针read指向的字符不同于下一个字符时,我们就认为读指针read 位于某一段连续相同子串的最右侧。该子串对应的字符即为读指针 read 指向的字符串。我们使用变量 left 记录该子串的最左侧的位置,这样子串长度即为 read-left+1。

这里还有一个问题,就是长度可能超过10,因此还要实现将数字转化为字符串写入到原字符串的功能。这里我们采用短除法将子串长度倒序写入原字符串中,然后再将其反转即可。

class Solution {public int compress(char[] chars) {int n = chars.length;int write = 0, left = 0;for (int read = 0; read < n; read++) {if (read == n - 1 || chars[read] != chars[read + 1]) {chars[write++] = chars[read];int num = read - left + 1;if (num > 1) {int anchor = write;while (num > 0) {chars[write++] = (char) (num % 10 + '0');num /= 10;}reverse(chars, anchor, write - 1);}left = read + 1;}}return write;}public void reverse(char[] chars, int left, int right) {while (left < right) {char temp = chars[left];chars[left] = chars[right];chars[right] = temp;left++;right--;}}
}

6. 总结

我们介绍了很多字符串的基本题目,这些题目在面试现场写代码时经常会遇到。可以看到这些题目的处理方式与数组问题一脉相承,在数组里经常用的双指针也可以使用。但是因为字符串本身的特殊性,又要做很多特殊的处理,例如空格等等。

另外很多字符串的问题必须先将字符串转换成数组才能处理,这需要我们对charAt()等方法非常熟悉才可以。很多人会在简历里写 “精通java基础开发”,但是如果String的用法都忘了,甚至现场问面试官官,你还觉得自己精通吗?

字符串有很多经典,但是比较难的题目,这个难在需要使用回溯、动态规划等方法来处理,此等问题更适合在高级算法中介绍。例如最长回文串和字符串匹配等等。我们在后续的动态规划再研究。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/1541816.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

OctoSQL 查询大量数据库和文件格式

OctoSQL 主要是一款 CLI 工具&#xff0c;可让你通过统一界面使用 SQL 查询大量数据库和文件格式&#xff0c;甚至在它们之间进行连接。同时&#xff0c;它还是一个易于扩展的完整数据流引擎&#xff0c;你可以用它为自己的应用程序添加 SQL 接口 OctoSQL是一款功能强大的SQL查…

Git从了解到操作

Git常用命令 基本的linux命令 ls / ll 查看当前目录( ls 是查看目录有哪些文件夹&#xff0c;ll 是查看隐藏文件)cat 查看文件内容touch 创建文件vi vi编辑器 (使用 vi 编辑器是为了方便展示效果&#xff0c;也可以记事本、editPlus、notPad等其它编辑器) 备注 Git GUl: Gi…

docker基本(仅供自己参考)

一、大型项目部署的问题&#xff1a; 1、大型项目的组件比较多&#xff0c;运行环境很复杂&#xff0c;部署通常会遇到各种问题&#xff1a; &#xff08;1&#xff09;&#xff1a;依赖关系复杂&#xff0c;容易出现兼容性问题 &#xff08;2&#xff09;&#xff1a;开发、…

雪花算法Snowflake

雪花算法常用于分布式的项目中&#xff0c;是为了解决大数据产生的多表分表中&#xff0c;保证id的唯一性。 1.分布式的特点 全局唯一性&#xff1a;不能出现有重复ID的标识&#xff1b;地增性&#xff1a;确保生成的ID对用于用户或业务是递增的&#xff1b;高可用性&#xf…

施耐德EcoStruxure Machine SCADA Expert(EMSE)与SQL数据库连接(十五)

我习惯使用SQL Server 数据库与EMSE进行连接。 用的是sql 2017 关于数据库软件的安装教程 网上一大把。 1.新建数据库 打开数据库管理工具&#xff0c;新建数据库 2.新建表单 &#xff08;ps:这里先做一个小测试-----目的是验证与EMSE软件的链接是否顺畅。) 添加两个元素进去…

flask的学习记录

结构如下&#xff1a; app.py from App import create_appapp create_app()if __name__ __main__:app.run(debugTrue,host0.0.0.0,port5000) App/__init__.py from flask import Flask, render_template, request, redirect, url_for from .views import blue from .exts …

VisualPromptGFSS

COCO-20 i ^i i太大&#xff0c;不建议复现

golang学习笔记1-go程序执行流程

声明&#xff1a;本人已有C&#xff0c;C,Python基础&#xff0c;只写本人认为的重点&#xff0c;方便自己回顾。 命令行执行go程序有两种方式&#xff0c;其流程如下图 注意第一种方式会得到可执行文件&#xff0c;第二种不会。 例1 在当前目录下编译hello.go go build hel…

TypeScript入门 (三)数据类型

引言 大家好&#xff0c;我是GISer Liu&#x1f601;&#xff0c;一名热爱AI技术的GIS开发者。本系列文章是我跟随DataWhale 2024年9月学习赛的TypeScript学习总结文档。本文旨在全面介绍 TypeScript 中的各种数据类型&#xff0c;帮助读者深入理解每种数据类型的用法、内置属性…

Matlab simulink建模与仿真 第十九章(生成C代码)

一、Configuration Parameters模型参数配置 1、仿真时间 &#xff08;1&#xff09;在Solver选项卡中可以设置仿真的起始时间和结束时间&#xff0c;一般起始时间设为0&#xff0c;而结束时间按需设置。 &#xff08;2&#xff09;如果希望仿真不会自动暂停&#xff08;也就…

Qwen大型语言模型系列的最新成果 ----Qwen2.5

通义千问2.5-7B-Instruct-GGUF 模型库 (modelscope.cn) apt install git-lfsgit lfs installgit clone https://www.modelscope.cn/qwen/Qwen2.5-7B-Instruct-GGUF.git

(done) 声音信号处理基础知识(3) (一个TODO: modulation 和 timbre 的关联)(强度、响度、音色)

来源&#xff1a;https://www.youtube.com/watch?vJkoysm1fHUw sound power 通常可以被认为是能量传输的速率 声源往所有方向传输的每时间单位能量 用 瓦特(W) 作为单位测量 Sound intensity 声音强度&#xff0c;每单位面积的 sound power W/m^2 人类实际上能听到非常小强…

Mybatis+Druid+MybatisPlus多数据源配置

MybatisDruidMybatisPlus多数据源配置 平常我们使用的是 properties 或者 yaml 来配置数据库的地址、用户名、密码等 但是这样只能配置一个数据源 现在我们想在一个项目里面配置多个数据源&#xff0c;那么我们就需要配置自己的配置类 配置类和配置文件 Mybatismysqldruid配置…

此框架你到底了解多少???

1.简述对Spring中IOC/DI的理解 IOC&#xff1a;控制反转&#xff0c;将创建和管理的对象的任务交给外部的Spring容器 DI&#xff1a;依赖注入&#xff0c;对象之间存在依赖关系&#xff0c;创建对象时&#xff0c;对其依赖的对应直接进行赋值 2.有哪些依赖注入的方式 基于注…

在线教程丨1 步生成 SOTA 级别图像,Hyper-SD 一键启动教程上线!

近年来&#xff0c;扩散模型在文生图任务中得到了广泛的应用&#xff0c;但其在实现高质量图像生成的过程中&#xff0c;通常需要多步推理进行去噪&#xff0c;这显然大大增加了计算资源成本。 针对于此&#xff0c;研究人员引入蒸馏算法&#xff0c;推出了扩撒感知蒸馏算法来…

超实用的 Typora 插件

&#x1f33c;&#x1f4da;Typora 是一款高效、易用且跨平台的 Markdown 编辑器和阅读器&#xff0c;其具有小巧、快速、实时预览等特点&#xff0c;非常受大家的欢迎。今天给大家推荐一款如虎添翼的 Typora 插件(Typora Plugin)&#xff0c;它可以通过插件增强 Typora 的功能…

什么是调制?FM 和 AM 有什么区别?

来源&#xff1a;https://www.bilibili.com/video/BV1pp411d7Zg/?spm_id_fromautoNext&vd_source7a1a0bc74158c6993c7355c5490fc600 一张图说明一切 原因&#xff1a;低频信号传输距离很近&#xff0c;高频信号传输距离较远。 为了把低频信号传出去&#xff0c;需要把低…

【数据结构C语言】【入门】【首次万字详细解析】入门阶段数据结构可能用到的C语言知识,一章让你看懂数据结构!!!!!!!

前言&#xff1a;欢迎各位光临本博客&#xff0c;这里小编带你直接手撕入门阶段的数据结构的C语言知识&#xff0c;让你不再看见数据结构就走不动道。文章并不复杂&#xff0c;愿诸君耐其心性&#xff0c;忘却杂尘&#xff0c;道有所长&#xff01;&#xff01;&#xff01;&am…

图片马赛克处理(Java)

1.需求 给图片的指定区域打码给整张图片打码马赛克方格取色支持中心点取色和随机取色马赛克支持灰度处理 2.源码 package com.visy.utils;import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOE…

我们如何通过两个关键测试原则,进行自动化 Kubernetes 配置和Secret测试

现如今&#xff0c;一个上规模的应用程序几乎都会使用 Kubernetes 作为管理环境实现自动扩展、负载平衡&#xff08;auto scaling, load balancing &#xff09;等机制。与之相应的&#xff0c;我们通常会使用一个 repository 专门管理一个组织内部各项不同应用程序在各个环境的…