小白挑战Java面试题!!!

题外话

这个题目有很多大佬去写了,用的方法也比我的要简单,但是因为我目前的水平还达不到,很多东西思维不理解,所以我就准备自己写一个较为基础的分析,如有错误,欢迎大家指正!
这里附上大佬们的链接:求无重复字符的最长子串

一、题目

求无重复字符的最长子串。

二、具体要求

给定一个字符串,请你找出其中不含有重复字符的最长子串的长度。

示例 1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3

示例 2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1

示例 3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3
 请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

三、题目分析

  1. 在分析题目之前我们首先要明确子串的概念。
    子串:串中任意个连续的字符组成的子序列称为该串的子串。对于一个字符串变量,例如"adereegfbw",它的子串就是像"ader"这样可以从中找到的连续的字符串。字符串"adereegfbw"本身也属于它本身最长的子串。
  2. 了解了子串的概念,接下来我们试着去计算一下我们最终应该得到什么样的结果。
//最长子串的长度为
3
//所有的子串
[a, ab, abc, b, bc, bca, c, ca, cab, cb]
  1. 经过了上面的两部,想必大家已经对题目有了一定程度的了解,接下来我们开始编程部分。

四、编程及代码

  1. 根据题目要求我们会得到一个字符串,然后求最长子串。这里我的想法是,直接操作字符串会有些不方便,所以我决定将字符串转成ArrayList集合来进行操作。
  2. 那么首先我们需要两个ArrayList集合来进行存储,List用来存储原字符串,List1用来存储子串。
 ArrayList<String> list = new ArrayList<>();
 ArrayList<String> list1 = new ArrayList<>();
        //将字符串s转换成Arraylist集合
        for (int i = 0; i <s.length(); i++) {
            list.add(String.valueOf(s.charAt(i)));
        }
  • 这里用到了valueOf() 方法,下面是API中的介绍。
    api
  1. 存储空间创建好后,接下来要来计算子串了,这里我们使用substring() 方法
    API
 //添加所有子串
   for (int i = 0; i < s.length(); i++) {
      for (int j = i+1 ; j < s.length(); j++) {
          String substring = s.substring(i, j);
            list1.add(substring);
            //去除自身含有重复元素的子串
              for (int k = 0; k < substring.length(); k++) {
                for (int l = k+1; l < substring.length(); l++) {
       if (substring.charAt(k)==substring.charAt(l)){
                            list1.remove(substring);
                        }
                    }
                }
            }
        }
         //去除list1集合中重复的子串
        for (int i = 0; i < list1.size() - 1; i++) {
            // 从list中索引为 list.size()-1 开始往前遍历
            for (int j = list1.size() - 1; j > i; j--) {
                // 进行比较
                if (list1.get(j).equals(list1.get(i))) {
                    // 去重
                    list1.remove(j);
                }
            }
        }
  • 因为使用了双for循环进行子串的添加,重复项较多,所以我们要进行去重操作,再次使用双for循环以及if语句判断子串的每个字母是否有重复的,如果有重复的则使用remove() 方法删除List1中重复的子串。(注意这里有两次去重操作,都是必不可少的!)
  1. 进行到这一步子串我们就求完了,但是别急这还没结束,题目让我们求的是:请你找出其中不含有重复字符的最长子串的长度 ,关键字是长度,所有我们还要求最长子串的长度,这里就比较简单了,毕竟我们已经把所有子串都求出来了,接下来我们用get().length() 方法求出指定子串的长度。并使用Arrays.stream(numbers).sorted() 方法将数组从大到小排序,最终numbers[0]存储的就是最长子串的长度了。
 //存储list集合中每个子串的长度,求其最大值
        int[] numbers = new int[list1.size()];
        for (int i = 0; i < list1.size(); i++) {
            numbers[i]=list1.get(i).length();
        }
        Arrays.stream(numbers).sorted();
        int max = numbers[0];

五、结果展示

3
[a, b, c, a, b, c, b, b]
[a, ab, abc, b, bc, bca, c, ca, cab, cb]

进程已结束,退出代码0

六、完整代码

import java.util.ArrayList;
import java.util.Arrays;

public class Test3 {
    public static void main(String[] args) {
        String s ="abcabcbb";
        lengthOfLongestSubstring(s);
    }
    private static void lengthOfLongestSubstring(String s){
        ArrayList<String> list = new ArrayList<>();
        ArrayList<String> list1 = new ArrayList<>();
        //将字符串s转换成Arraylist集合
        for (int i = 0; i <s.length(); i++) {
            list.add(String.valueOf(s.charAt(i)));
        }
        //去除原字符串中重复的元素,并添加到集合中
//        for (int i = 0; i < list.size(); i++) {
//            boolean contains = list1.contains(list.get(i));
//            if (!contains){
//                list1.add(list.get(i));
//            }
//        }
        //返回所有子串
        for (int i = 0; i < s.length(); i++) {
            for (int j = i+1 ; j < s.length(); j++) {
                String substring = s.substring(i, j);
                list1.add(substring);
                for (int k = 0; k < substring.length(); k++) {
                    for (int l = k+1; l < substring.length(); l++) {
                        if (substring.charAt(k)==substring.charAt(l)){
                            list1.remove(substring);
                        }
                    }
                }
            }
        }


        //去除list集合中重复的元素
//        for (int i = 0; i < list1.size(); i++) {
//            for (int j = 1; j < list1.size(); j++) {
//                if (list1.get(i)==list1.get(j)){
//                    list1.remove(j);
//                }
//            }
//        }
        //去除list集合中重复的元素
        for (int i = 0; i < list1.size() - 1; i++) {
            // 从list中索引为 list.size()-1 开始往前遍历
            for (int j = list1.size() - 1; j > i; j--) {
                // 进行比较
                if (list1.get(j).equals(list1.get(i))) {
                    // 去重
                    list1.remove(j);
                }
            }
        }

        //存储list集合中每个子串的长度,求其最大值
        int[] numbers = new int[list1.size()];
        for (int i = 0; i < list1.size(); i++) {
            numbers[i]=list1.get(i).length();
        }
        Arrays.stream(numbers).sorted();
        int max = numbers[0];

        System.out.println(max);
        System.out.println(list);
        System.out.println(list1);
    }
}

七、总结

  • 实现的方法较为麻烦,用了很多for循环,但是个人觉得思想上容易理解,就是复杂度稍稍高一些。希望对大家有用,感谢!
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值