经典题目刷一刷

 再~~~

目录

1.删除公共字符串

2.倒置字符串

3.字符串的排列

4.无重复字符的最长子串


1.删除公共字符串

删除公共字符_牛客题霸_牛客网【牛客题霸】收集各企业高频校招笔面试题目,配有官方题解,在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨论经典试题,全面提升你的技术能力https://www.nowcoder.com/practice/f0db4c36573d459cae44ac90b90c6212?tpId=85&&tqId=29868&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking

①题目示例:

②方法解析:

本题我们可以逆向思维来看待,题目要求是只要是字符串二中出现的字符,那么相应在字符串一中必须删除。换言之,我们可以把字符串二中没出现的字符给留下来,那么形成的新的字符串就是我们要求的字符串了

代码:

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.倒置字符串

倒置字符串_牛客题霸_牛客网【牛客题霸】收集各企业高频校招笔面试题目,配有官方题解,在线进行百度阿里腾讯网易等互联网名企笔试面试模拟考试练习,和牛人一起讨论经典试题,全面提升你的技术能力https://www.nowcoder.com/practice/ee5de2e7c45a46a090c1ced2fdc62355?tpId=85&&tqId=29867&rp=1&ru=/activity/oj&qru=/ta/2017test/question-ranking

①题目示例:

②方法解析一:(分割字符串的方法)

直接采用分割字符串的方法,以" "为分割线,进行分割成三个部分,分割完成后被接收成为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.无重复字符的最长子串

3. 无重复字符的最长子串 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/

①题目示例:

②方法解析:

本题要求要找最长不重复的字符串,那么只要出现重复的了,我们就需要再一次从重复的后一位进行再次记录。最后比较每次记录的最大值,返回最大值即可 

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;
    }
}
  • 31
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 43
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 43
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

张洋洋~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值