最長非重複子字符串

原題

  Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for 「abcabcbb」 is 「abc」, which the length is 3. For 「bbbbb」 the longest substring is 「b」, with the length of 1.java

題目大意

  給定一個字符串,找字符中的最大非重複子串app

解題思路

  用start記錄當前處理的開始位置 歷遍字符串,噹噹前字符從開始位置start開始已經出現過的時候,子串開始位置+1,不然更新map中的hash值爲當前位置spa

代碼實現

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

/**
 * Author: 王俊超
 * Date: 2015-06-17
 * Time: 20:46
 * Declaration: All Rights Reserved !!!
 */
public class Solution {
    /**
     * 003-Longest Substring Without Repeating Characters(最長非重複子字符串)
     *
     * @param s 輸入字符串
     * @return 最大非重複子串長度
     */
    // 能夠處理全部的UTF-8字符
    public int lengthOfLongestSubstring(String s) {
        // 字符串輸入不合法
        if (s == null) {
            return 0;
        }

        // 當前處理的開始位置
        int start = 0;
        // 記錄到的最大非重複子串長度
        int result = 0;
        // 訪問標記,記錄最新一次訪問的字符和位置
        Map<Character, Integer> map = new HashMap<>(s.length());

        for (int i = 0; i < s.length(); i++) {
            char ch = s.charAt(i);
            // 若是字符已經出現過(在標記開位置算起),就從新標記start
            if (map.containsKey(ch) && map.get(ch) >= start) {
                start = map.get(ch) + 1;
            }
            // 若是沒有出現過就求最大的非重複子串的長度
            else {
                result = Math.max(result, i - start + 1);
            }

            // 更新訪問記錄
            map.put(ch, i);
        }
        return result;
    }

    // 只考慮ASCII字符【解法二】
    public int lengthOfLongestSubstring2(String s) {
        // 字符串輸入不合法
        if (s == null) {
            return 0;
        }

        // 標記字符是否出現過,而且記錄是的最新一次訪問的元素的位置
        int[] appear = new int[256];
        // 初始化爲-1
        Arrays.fill(appear, -1);
        // 當前處理的開始位置
        int start = 0;
        // 保存結果
        int result = 0;

        for (int i = 0; i < s.length(); i++) {
            // 若是字符已經出現過(在標記開位置),就從新標記start
            if (appear[s.charAt(i)] >= start) {
                start = i + 1;
            }
            // 若是沒有出現過就求最大的非重複子串的長度
            else {
                result = Math.max(result, i - start + 1);
            }
            // 標記第i個字符已經被訪問過(最新是第i個位置)
            appear[s.charAt(i)] = i;
        }

        return result;
    }
}
相關文章
相關標籤/搜索