小浩算法-java题解-字符串篇
字符串篇
第344题:反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入:["h","e","l","l","o"]
输出:["o","l","l","e","h"]
解题思路:双指针一个指向头,一个指向尾,用一个tmp交换头尾,直到头和尾一样。
class Solution {
public void reverseString(char[] s) {
int start=0,end=s.length-1;
while(start<end)
{
char tem=s[start];
s[start]=s[end];
s[end]=tem;
start++;end--;
}
}
}
第387题:字符串中的第一个唯一字符
给定一个字符串,找到它的第一个不重复的字符,并返回它的索引。如果不存在,则返回 -1 。
案例:
s = "leetcode"
返回 0.
s = "loveleetcode",
返回 2.
**注意事项:**您可以假定该字符串只包含小写字母。
解题思路:两遍遍历,第一次遍历用哈希表存储字符串的每一个元素和次数,第二次遍历把出现次数为1的找到然后打印索引。
class Solution {
public int firstUniqChar(String s) {
HashMap<Character,Integer> map=new HashMap<Character,Integer>();
for(int i=0;i<s.length();i++)
{
char c=s.charAt(i);
map.put(c,map.getOrDefault(c,0)+1);
}
for(int i=0;i<s.length();i++)
{
if(map.get(s.charAt(i))==1) return i;//如果当前元素的次数为1,那么说明找到了这个元素,返回索引即可
}
return -1;//说明没有这个元素
}
}
题目28:实现 strStr()
实现 strStr() 函数。给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needle 字符串出现的第一个位置 (从0开始)。如果不存在,则返回 -1。
示例 1:
输入: haystack = "hello", needle = "ll"
输出: 2
**注意事项:**您可以假定该字符串只包含小写字母。
解题思路:sunday没整明白,用的官解。
有点像滑窗,每次用模式串来和目标串进行对比。
class Solution {
public int strStr(String haystack, String needle) {
int hl=haystack.length(),nl=needle.length();
for(int i=0;i<hl-nl+1;i++)
{
if(haystack.substring(i,i+nl).equals(needle)) return i;
}
return -1;
}
}
剑指 Offer 17题目:大数打印
输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
示例 1:
输入: n = 1
输出: [1,2,3,4,5,6,7,8,9]
解题思路:
方法一:用Math.pow确定要打印的长度
class Solution {
public int[] printNumbers(int n) {
int len=(int)Math.pow(10,n);
int ans[]=new int[len-1];
for(int i=1;i<len;i++)
{
ans[i-1]=i;
}
return ans;
}
}
方法二:
计数形式的记下来然后打印出来
class Solution {
public int[] printNumbers(int n) {
int l=0;
while(0<n)
{
n--;
l=l*10+9;
}
int ans[]=new int[l];
for(int i=1;i<=l;i++)
ans[i-1]=i;
return ans;
}
}
方法三:字符串记录。详情看这个大佬的。
第125题:验证回文串
给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。
说明: 本题中,我们将空字符串定义为有效的回文串。
示例 1:
输入: "A man, a plan, a canal: Panama"
输出: true
解题思路:先全部搞成小写,然后过滤掉不比较的,然后用双指针来比较头和尾。
class Solution {
public boolean isPalindrome(String s) {
s=s.toLowerCase();
char c[]=s.toCharArray();
int i=0;
int j=s.length()-1;
while(i<j)
{
if (!((c[i] >= '0' && c[i] <= '9') || (c[i] >= 'a' && c[i] <= 'z')))
{
i++;
continue;
}
if (!((c[j] >= '0' && c[j] <= '9') || (c[j] >= 'a' && c[j] <= 'z')))
{
j--;
continue;
}
if(c[i]!=c[j])
return false;
i++;
j--;
}
return true;
}
}
第796题:旋转字符串
给定两个字符串, A 和 B。A 的旋转操作就是将 A 最左边的字符移动到最右边。例如, 若 A = ‘abcde’,在移动一次之后结果就是’bcdea’ 。如果在若干次旋转操作之后,A 能变成B,那么返回True。
示例 1:
输入: A = 'abcde', B = 'cdeab'
输出: true
解题思路:
方法一:把A串的每一个元素向后移,然后再和B进行比较。
class Solution {
public boolean rotateString(String A, String B) {
if(A.equals("") && B.equals(""))
return true;
int len=A.length();
for(int i=0;i<len;i++)
{
String first=A.substring(0,1);
String last=A.substring(1,len);
A=last+first;
if(A.equals(B)) return true;
}
return false;
}
}
方法二:无论怎么移,B符合条件的话一定是A+A的子串,所以判断B是不是A+A的子串就好了。
class Solution {
public boolean rotateString(String A, String B) {
return A.length()==B.length()&& (A+A).contains(B);
}
}
第58题:最后一个单词的长度
给定一个仅包含大小写字母和空格 ’ ’ 的字符串 s,返回其最后一个单词的长度。如果字符串从左向右滚动显示,那么最后一个单词就是最后出现的单词。
示例:
输入: "Hello World"
输出: 5
说明: 一个单词是指仅由字母组成、不包含任何空格字符的 最大子字符串。
解题思路:从最后一个不为空的地方开始计数,计数为ans,比如"AAA bbb CCCC "就是在最后一个C开始计数的,如果末尾是空格,并且ans为0,那么略过。
class Solution {
public int lengthOfLastWord(String s) {
int len=s.length();
int ans=0;
for(int i=len-1;i>=0;i--)
{
if(s.charAt(i)==' ')
{
if(ans==0) continue;
break;
}
else ans++;
}
return ans;
}
}