【笔试实战】LeetCode题单刷题-编程基础 0 到 1【一】
1768. 交替合并字符串
题目链接
题目描述
给你两个字符串 word1
和 word2
。请你从 word1
开始,通过交替添加字母来合并字符串。如果一个字符串比另一个字符串长,就将多出来的字母追加到合并后字符串的末尾。
返回 合并后的字符串 。
示例 1:
输入:word1 = "abc", word2 = "pqr"
输出:"apbqcr"
解释:字符串合并情况如下所示:
word1: a b c
word2: p q r
合并后: a p b q c r
示例 2:
输入:word1 = "ab", word2 = "pqrs"
输出:"apbqrs"
解释:注意,word2 比 word1 长,"rs" 需要追加到合并后字符串的末尾。
word1: a b
word2: p q r s
合并后: a p b q r s
示例 3:
输入:word1 = "abcd", word2 = "pq"
输出:"apbqcd"
解释:注意,word1 比 word2 长,"cd" 需要追加到合并后字符串的末尾。
word1: a b c d
word2: p q
合并后: a p b q c d
提示:
1 <= word1.length, word2.length <= 100
word1
和word2
由小写英文字母组成
解题思路一【Java语言】
时间6 ms 击败 12.69%
内存40.6 MB 击败 10.66%
在这个程序中,我们需要将两个字符串按照交替的顺序合并起来。我们首先找到两个字符串的最小长度和最大长度。然后,我们用一个循环将两个字符串的字符按照交替的顺序逐个取出来,并将它们相加到一个新的字符串中。如果有一个字符串的长度较短,那么我们需要将较长的字符串中剩余的字符都添加到结果字符串的末尾。最后,我们返回合并后的字符串作为结果。
这个程序涉及到以下几个知识点:
- 字符串长度和字符访问:通过调用字符串的length()方法可以获取字符串的长度,通过调用charAt()方法可以访问字符串中的指定位置的字符。
- 循环:使用for循环来对两个字符串的字符进行遍历操作。
- 字符串拼接:使用+操作符可以将两个字符串拼接成一个新的字符串。
- 字符串截取:使用substring()方法可以从一个字符串中截取指定位置的子字符串。
- 数学函数:使用Math.min()和Math.max()函数可以分别找到两个数字中的最小值和最大值。
- 字符串的基本操作:对字符串进行长度比较和截取字符。
class Solution {
public String mergeAlternately(String word1, String word2) {
int finalMinLength=Math.min(word1.length(), word2.length());
int finalMaxLength=Math.max(word1.length(), word2.length());
String result="";
int i=0;
for(i=0;i<finalMinLength;i++){
result+=(word1.substring(i,i+1)+word2.substring(i,i+1));
}
if(finalMinLength==finalMaxLength){
return result;
}else if(finalMinLength==word1.length()){
result+=word2.substring(i);
}else{
result+=word1.substring(i);
}
return result;
}
}
389. 找不同
题目链接
题目描述
给定两个字符串 s
和 t
,它们只包含小写字母。
字符串 t
由字符串 s
随机重排,然后在随机位置添加一个字母。
请找出在 t
中被添加的字母。
示例 1:
输入:s = "abcd", t = "abcde"
输出:"e"
解释:'e' 是那个被添加的字母。
示例 2:
输入:s = "", t = "y"
输出:"y"
提示:
0 <= s.length <= 1000
t.length == s.length + 1
s
和t
只包含小写字母
- 位运算
- 哈希表
- 字符串
- 排序
解题思路一【Java语言】
时间1 ms 击败 98.85%
当我们把两个相同的数进行异或运算时,结果为 0。所以如果字符串 t 是由字符串 s 随机重排并在随机位置添加一个字母得到的,那么 t 中的所有字符都可以与 s 中的相应字符进行异或运算,最后得到的结果就是添加的字母。
具体步骤如下:
- 定义一个变量 result,并初始化为 0。
- 遍历字符串 s 的每个字符,对每个字符执行异或运算。
- 遍历字符串 t 的每个字符,对每个字符执行异或运算。
- 异或运算会将两个二进制位不同的位置设为 1,相同的位置设为 0。因此,最后运算的结果就是添加的字母。
假设有以下输入:
s = "hello" t = "lohlel"
我们可以按照以下步骤来解释算法的运行:
首先,对字符串 s 进行遍历,依次进行异或运算:
- 遍历到 'h',结果 result = 'h' ^ 0 = 'h'
- 遍历到 'e',结果 result = 'h' ^ 'e' = 'h' ^ 'e'
- 遍历到 'l',结果 result = 'h' ^ 'e' ^ 'l' = 'h' ^ 'e' ^ 'l'
- 遍历到 'l',结果 result = 'h' ^ 'e' ^ 'l' ^ 'l' = 'h' ^ 'e' ^ 'l' ^ 'l'
- 遍历到 'o',结果 result = 'h' ^ 'e' ^ 'l' ^ 'l' ^ 'o' = 'h' ^ 'e' ^ 'l' ^ 'l' ^ 'o'
然后,对字符串 t 进行遍历,同样进行异或运算:
- 遍历到 'l',结果 result = 'h' ^ 'e' ^ 'l' ^ 'l' ^ 'o' ^ 'l' = 'h' ^ 'e' ^ 'o' ^ 'l'
- 遍历到 'o',结果 result = 'h' ^ 'e' ^ 'o' ^ 'l' ^ 'o' = 'h' ^ 'e' ^ 'l'
- 遍历到 'h',结果 result = 'h' ^ 'e' ^ 'l' ^ 'h' = 'e' ^ 'l'
- 遍历到 'l',结果 result = 'e' ^ 'l' ^ 'l' = 'e'
- 遍历到 'e',结果 result = 'e' ^ 'e' = 0
最后的结果为 0,表示在 t 中被添加的字母是 'e'。
通过对 s 和 t 进行异或运算,最后运算的结果就是被添加的字母。
程序用到的知识点包括:
- 异或运算
class Solution {
public char findTheDifference(String s, String t) {
char result = 0;
for (char c : s.toCharArray()) {
result ^= c;
}
for (char c : t.toCharArray()) {
result ^= c;
}
return result;
}
}
28. 找出字符串中第一个匹配项的下标
题目链接
题目描述
给你两个字符串 haystack
和 needle
,请你在 haystack
字符串中找出 needle
字符串的第一个匹配项的下标(下标从 0 开始)。如果 needle
不是 haystack
的一部分,则返回 -1
。
示例 1:
输入:haystack = "sadbutsad", needle = "sad"
输出:0
解释:"sad" 在下标 0 和 6 处匹配。
第一个匹配项的下标是 0 ,所以返回 0 。
示例 2:
输入:haystack = "leetcode", needle = "leeto"
输出:-1
解释:"leeto" 没有在 "leetcode" 中出现,所以返回 -1 。
提示:
1 <= haystack.length, needle.length <= 104
haystack
和needle
仅由小写英文字符组成
解题思路一【Java语言】
时间0 ms 击败 100%
内存39.4 MB 击败 64.64%
这道题划归为中等难度着实有些无语了
class Solution {
public int strStr(String haystack, String needle) {
return haystack.indexOf(needle);
}
}
242. 有效的字母异位词
题目链接
题目描述
给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的字母异位词。
注意:若 s
和 t
中每个字符出现的次数都相同,则称 s
和 t
互为字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram"
输出: true
示例 2:
输入: s = "rat", t = "car"
输出: false
提示:
1 <= s.length, t.length <= 5 * 104
s
和t
仅包含小写字母
进阶: 如果输入字符串包含 unicode 字符怎么办?你能否调整你的解法来应对这种情况?
- 哈希表
- 字符串
- 排序
解题思路一【Java语言】
时间340 ms 击败 5.49%
解题思路如下:
- 创建两个字符数组a1和a2,分别存储字符串s和t的字符。
- 使用Arrays类的sort方法对a1和a2进行排序,使得两个数组中的字符按照字典序排序。
- 创建两个空字符串resultA和resultB,分别用于存储排序后的a1和a2。
- 遍历a1和a2,将每个字符依次追加到resultA和resultB。
- 最后,判断resultA和resultB是否相等。如果相等,则s和t是字母异位词,返回true;否则,返回false。
class Solution {
public boolean isAnagram(String s, String t) {
char [] a1=s.toCharArray();
char [] a2=t.toCharArray();
Arrays.sort(a1);
Arrays.sort(a2);
String resultA="";
String resultB="";
for (char c : a1) {
resultA+= c;
}
for (char c : a2) {
resultB+= c;
}
return resultA.equals(resultB);
}
}
程序用到的知识点包括:
- 字符串转字符数组:使用toCharArray方法。
- 字符数组排序:使用Arrays类的sort方法。
- 字符串拼接:通过循环遍历字符数组,将每个字符依次追加到字符串中。
- 字符串比较:使用equals方法判断两个字符串是否相等。
459. 重复的子字符串
题目链接
题目描述
给定一个非空的字符串 s
,检查是否可以通过由它的一个子串重复多次构成。
示例 1:
输入: s = "abab"
输出: true
解释: 可由子串 "ab" 重复两次构成。
示例 2:
输入: s = "aba"
输出: false
示例 3:
输入: s = "abcabcabcabc"
输出: true
解释: 可由子串 "abc" 重复四次构成。 (或子串 "abcabc" 重复两次构成。)
提示:
1 <= s.length <= 104
s
由小写英文字母组成
解题思路一【Java语言】
时间83 ms 击败 23.96%
内存42.8 MB 击败 43.30%
- s+s
- 破坏到第一个s的前半部分,破坏掉第二个s的后半部分
- 如果是一个子串重复多次构成,则第一个s的后半部分和第二个s的前半部分一定可以拼凑成一个s
- 如果不是,肯定拼凑不出来
- 即s+s,掐头去尾找自己
class Solution {
public boolean repeatedSubstringPattern(String s) {
String str = s+s;
str = str.substring(1,str.length() - 1);
return str.contains(s);
}
}
283. 移动零
题目链接
题目描述
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums = [0,1,0,3,12] 输出: [1,3,12,0,0]
示例 2:
输入: nums = [0] 输出: [0]
提示:
1 <= nums.length <= 104
-231 <= nums[i] <= 231 - 1
解题思路一【Java语言】
时间1 ms 击败 100%
可以使用双指针的方法,一个指针用于遍历数组,另一个指针指向下一个非零元素应该插入的位置。
具体步骤如下:
-
初始化两个指针,i指向当前遍历的元素,j指向下一个非零元素应该插入的位置。
-
遍历数组,如果当前元素为0,则继续遍历下一个元素;如果当前元素不为0,则将当前元素复制到j指向的位置,并将i和j都加1。
-
遍历完数组后,将j之后的所有元素都置为0,以保证数组长度不变。
class Solution {
public void moveZeroes(int[] nums) {
int i = 0, j = 0;
for (; i < nums.length; i++) {
if (nums[i] != 0) {
nums[j] = nums[i];
j++;
}
}
while (j < nums.length) {
nums[j] = 0;
j++;
}
}
}
程序涉及到以下的一些知识点:
-
数组操作:对数组进行遍历、修改数组元素的值等等。
-
双指针:使用两个指针来进行数组操作,一个指向当前遍历的元素,另一个指向下一个非零元素应该插入的位置。
-
条件判断:在遍历数组的过程中,通过条件判断来判断当前元素是否为0。
-
数组长度:使用数组长度来确定遍历的范围和数组的结束位置。
66. 加一
题目链接
题目描述
给定一个由 整数 组成的 非空 数组所表示的非负整数,在该数的基础上加一。
最高位数字存放在数组的首位, 数组中每个元素只存储单个数字。
你可以假设除了整数 0 之外,这个整数不会以零开头。
示例 1:
输入:digits = [1,2,3]
输出:[1,2,4]
解释:输入数组表示数字 123。
示例 2:
输入:digits = [4,3,2,1]
输出:[4,3,2,2]
解释:输入数组表示数字 4321。
示例 3:
输入:digits = [0]
输出:[1]
提示:
1 <= digits.length <= 100
0 <= digits[i] <= 9
解题思路一【Java语言】
时间11 ms 击败 0.89%
内存40.7 MB 击败 5.18%
具体步骤如下:
- 将整数数组中的每个元素转换为字符串,并拼接起来得到一个表示整数的字符串。
- 使用BigInteger类将字符串表示的整数转换为BigInteger对象。
- 使用BigInteger的add方法将该对象加一。
- 将加一后的BigInteger对象转换为字符串,并将字符串转换为字符数组。
- 遍历字符数组,将每个字符转换为对应的数字,存入一个新的整数数组。
- 返回新的整数数组。
import java.math.BigInteger;
class Solution {
public int[] plusOne(int[] digits) {
int length=digits.length;
String sum="";
for(int i=0;i<length;i++){
sum=sum+digits[i];
}
BigInteger number=new BigInteger(sum);
number=number.add(BigInteger.ONE);
char[] charArray = number.toString().toCharArray();
int[] intArray = new int[charArray.length];
for(int i = 0; i < charArray.length; i++) {
intArray[i] = Character.getNumericValue(charArray[i]);
}
return intArray;
}
}
这个程序用到了以下知识点:
- 数组:使用int[] digits表示整数数组。
- 字符串操作:使用String类将整数数组元素转换为字符串,并通过字符串拼接进行数字的拼接。
- 大整数操作:使用BigInteger类进行大整数的运算。
- 字符串-字符转换:使用String类的toCharArray方法将字符串转换为字符数组。
- 字符-数字转换:使用Character类的getNumericValue方法将字符转换为对应的数字。
工程日志
2023-07-02
- LeetCode有些题目的标签确实是不尽合理,459. 重复的子字符串虽然是简单但是确实是花了很多时间想,但是像28. 找出字符串中第一个匹配项的下标就一句代码就绝了
- 有些题目如果十几二十分钟脑中空白那基本是想不到解决方法了,直接看题解,这是经验不够的问题,一道题想很久才做出来也没意义,因为竞赛和面试不会给这么多时间
- 有的时候不要被题目本身的介绍所局限,有的时候需要跳出题目误导的思维,找另一条路解开是更合适的方法