再接再厉~~~
目录
1.删除公共字符串
①题目示例:
②方法解析:
本题我们可以逆向思维来看待,题目要求是只要是字符串二中出现的字符,那么相应在字符串一中必须删除。换言之,我们可以把字符串二中没出现的字符给留下来,那么形成的新的字符串就是我们要求的字符串了
代码:
import java.util.*; class Main{ public static void main(String[]args){ Scanner sc=new Scanner(System.in); //输入字符串一: String a=sc.nextLine(); //输入字符串二: String b=sc.nextLine(); Map<Character,Integer>map=new HashMap<>(); //将第二个字符串中的值都存储在map中: for(int i=0;i<b.length();i++){ if(map.get(b.charAt(i)) == null) { map.put(b.charAt(i),1); }else { map.put(b.charAt(i),map.get(b.charAt(i))+1); } } //对字符串一中不在map中的字符添加到新的字符串中 StringBuilder sb=new StringBuilder(); for(int i=0;i<a.length();i++){ if(map.get(a.charAt(i))==null){ sb.append(a.charAt(i)); } } System.out.println(sb); } }
2.倒置字符串
①题目示例:
②方法解析一:(分割字符串的方法)
直接采用分割字符串的方法,以" "为分割线,进行分割成三个部分,分割完成后被接收成为String类型数组的三个位置,我们再倒序输出它的三个位置对应的值就能够能到题目要求
代码:
import java.util.*; class Main1 { public static void main(String[] args) { Scanner sc=new Scanner(System.in); String[] ret=sc.nextLine().split(" "); StringBuilder sb=new StringBuilder(); for(int i= ret.length-1;i>=0;i--){ sb.append(ret[i]); sb.append(" "); } //trim()方法是存在于String中的方法,在StringBuilder中是并不存在的,所以先将其转换成String,再调用 //trim()去除字符串左右两边的空格,但不不能去除中间的空格 String ret1=sb.toString().trim(); System.out.println(ret1); } }
②方法解析二:(利用逆转倒置来求)
利用双指针法,先把整个字符串转化为数组后进行倒置,然后把每个字符串的局部部分再进行倒置
代码:
import java.util.*; class Main1 { //双指针法实现转换倒置的方法 public static void reverse(char[]tmp,int left,int right) { while (left <= right) { char temp = tmp[left]; tmp[left] = tmp[right]; tmp[right] = temp; left++; right--; } } public static void main(String[] args) { Scanner sc=new Scanner(System.in); String ret=sc.nextLine(); char[]tmp=ret.toCharArray(); int left=0; int right=tmp.length-1; reverse(tmp,left,right); //当left<数组长度时的循环条件,要是不设置这个条件将会倒置最后一个局部的数无法实现逆转 while(left< tmp.length){ //设置一个变量ret1等于left的值用来进行移动的记录,而left始终作为每个part进行逆转前的左边缘部分 int ret1=left; while(ret1<tmp.length&&tmp[ret1]!=' '){ ret1++; }if(ret1<tmp.length){ reverse(tmp,left,ret1-1); //更新left在下一个part逆转前的左边缘位置 left=ret1+1; }else { reverse(tmp,left,ret1-1); left=ret1; } } //新建一个String类型的str用来存放逆转后的字符串 String str=new String(tmp); System.out.println(tmp); } }
3.字符串的排列
567. 字符串的排列 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/permutation-in-string/
①题目示例:
②方法解析:(滑动窗口法)
因为需要判断的是s2是否包含的s1,实质上来讲要判断包含,需要具备两个条件。一个是字符类型的一致性,另一个是同类型的数量的一致性。所以我们采用一边滑动窗口,一边记录的方式,最后来判断是否是一致的结果。
滑动窗口的具体体现:每次移动s1大小的窗口,每次移动一个位置,即左减一,右加一。当然要是s1的长度大于了s2的长度,很显然,这样的结果是不复存在的,直接返回false,即可
代码:(这里巧妙地采用了Ascll值进行转换)
class Solution { public boolean checkInclusion(String s1, String s2) { int n = s1.length(), m = s2.length(); if (n > m) { return false; } //因为此处的要求是小写,所以26个字母就对应了数组的大小 int[] cnt1 = new int[26]; int[] cnt2 = new int[26]; //先以s1的大小进行遍历,并记录其值的个数 for (int i = 0; i < n; ++i) { ++cnt1[s1.charAt(i) - 'a']; ++cnt2[s2.charAt(i) - 'a']; }//比较两个数组中目前的类型和数目是否一致,若已经一致,则无需再进入后面的判断 if (Arrays.equals(cnt1, cnt2)) { return true; }//接着按照进一退一的方式移动窗口,直到找到相等的后退出循环 for (int i = n; i < m; ++i) { ++cnt2[s2.charAt(i) - 'a']; --cnt2[s2.charAt(i - n) - 'a']; if (Arrays.equals(cnt1, cnt2)) { return true; } }//执行完都没有找到,即直接返回false return false; } }
4.无重复字符的最长子串
①题目示例:
②方法解析:
本题要求要找最长不重复的字符串,那么只要出现重复的了,我们就需要再一次从重复的后一位进行再次记录。最后比较每次记录的最大值,返回最大值即可
a.利用队列来解决,因为队列遵循先进先出的原则,那么我们每次判断一下即将入队的元素在队列中是否存在,要是存在,判断它是不是队首元素,若是队首元素,则直接将其出队,若不是的话,就一直出队,直到是队首位置为止再出一次,若是队列不存在则执行入队操作。而比较的对象即为每次更新前后当前队列的数的大小。
代码:
class Solution { public int lengthOfLongestSubstring(String s) { char[] a = s.toCharArray(); //建立一个空队列 Queue<Character> queue = new LinkedList<>(); //比较队列值和最大长度最大者为新的最大长度 int maxLength = 0; int begin = 0; for(int i = 0; i < a.length; i++){ if(queue.contains(a[i])){ while(queue.peek() != a[i]){ //如果队顶不是a[i],丢掉 queue.poll(); } //直到找到相等元素 queue.poll();//出队 } queue.offer(a[i]); maxLength = Math.max(queue.size(), maxLength); } return maxLength; } }