leetcode3. 无重复字符的最长子串--辅助数组--ASCII--结合简单例子纸上分析流程才清晰

1、解题思路–辅助数组–ASCII

用一个数组存放字符串出现过的位置index。

开始遍历字符串:
若没出现过字符,tmp长度➕1;
若发现出现过该字符串,tmp重计:

若上次出现的位置较远,当前字符位置与上一次出现的位置相减大于当前tmp长度,则不管它,tmp➕1;
若上次出现的位置较近,当前字符位置与上一次出现的位置相减小于当前tmp长度,则tmp长度按照位置差重新计数;
每次都更新位置index。

时间复杂度O(n)

来源:力扣(LeetCode):
思路来源链接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/solution/cyu-yan-jian-dan-jie-fa-by-pang-san-jin-3/

package com.company;

public class leetCode {
    public static void main(String[] args) {
        Solution solution = new Solution();
        int i = solution.find1("abcasdc");
        System.out.println(i);
    }
}

package com.company;

import java.util.HashMap;
import java.util.Map;

public class Solution {
//方法一  hashmap
    public int find(String s) {
        Map<Character, Integer> reMap = new HashMap();
        //最长子串
        int max = 0;
        //慢指针
        int left = 0;
        //快指针
        int i = 0;
        while (i < s.length()) {
            //如果存在重复的键时,需要将慢指针向左边移动
            //虽然左边的位置有移动 -- 不需要将重复的值进行修改成0
            if (reMap.containsKey(s.charAt(i))) {
                if (reMap.get(s.charAt(i)) >= left) {
                    left = reMap.get(s.charAt(i)) + 1;
                }
            }
            //快指针的不存在于哈希表的情况
            //如果原来哈希表中已经存在相同的键值时候,将会取代旧的值(如果原来的值存在就取代原来的值)
            reMap.put(s.charAt(i), i);
            i++;
            //统计最大字符子串
            if ((i - left) > max) {
                max = (i - left);
            }
        }
        return max;
    }

    //ASCII辅助数组的简单解法
    public int find1(String s) {
        int i;
        int ret = 0;
        int tmp = 0;
        char[] stoarr = s.toCharArray();
        int[] arr = new int[128];
        for (i = 0; i < stoarr.length; i++) {
            System.out.println(stoarr[i]);
            int index = (int) stoarr[i];
            //如果没有重复的字符
            if (arr[index] == 0) {
                ++tmp;
                //     arr[index] =1;
                System.out.println("看那些是不重复的部分" + " " + i);
            } else {
                //如果已经在数组中存在的处理
                //需要判断重复的字符是在此时字符串的的开始的位置之前
                //字符串的长度更新之后增加了 比 原来保存的最大值的个数时 需要及时的更新
                ret = (ret >= tmp) ? ret : tmp;
                System.out.println("ret" + ret);
                //需要滑动次窗口的左侧同时 更新此时的最长子串
                tmp = (tmp >= i + 1 - arr[index]) ? i + 1 - arr[index] : tmp;
                System.out.println("+" + (i + 1 - arr[index]) + tmp);
            }
            //高明之处是记录已经遍历的字符的最后 --  是第几个遍历的
            //此处不能从0开始是因为 等于0 如果第一个元素重复出现 -- 不能识别字符已经存在
            // arr[index] = i ;
            arr[index] = i + 1;//第一次在这里花费的时间比较多
        }
        ret = (ret >= tmp) ? ret : tmp;
        return ret;
    }
}

2、结合简单的例子 – abcasdc–分析算法流程–发现问题

arr[index] = i+k (k !=0) 才行。
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值