leetcode刷题笔记三 最长不重复子串 Scala版本

leetcode刷题笔记三 最长不重复子串 Scala版本

原地址:[https://leetcode.com/problems/longest-substring-without-repeating-characters/]:最长不重复子串

问题描述

题干

Given a string, find the length of the longest substring without repeating characters.

例子

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

简要思路分析:

1.暴力法

2.结合动态规划的思想,在对字符串的遍历过程中,分析收到的字符是否已经获得,如果不是,对应的位置length+1, maxLength继续更新;如果是,将最长串的from+1。

a b c a b c b b
1 2 3 3 3 3 2 1

代码补充:

import scala.collection.mutable.Set
object Solution {
    def lengthOfLongestSubstring(s: String) = {
    var length = 0
    var maxLength = 0
    var prePose = 0
    var mMap = Map[Int, Int]()
    var mSet = Set(s(0))

    mMap += (0->1)

    if (s == null || s.length == 0){
      null
    }


    for (i <- 1 until s.length){

      if (mSet.contains(s(i))){
        val from:Int =  s.substring(prePose,i).indexOf(s(i)) + prePose
        val to:Int = i
        length = to - from
        prePose = from + 1
        mMap += (i->length)
      }
      else{
        mSet.add(s(i))
        var temp = mMap(i-1)+1
        mMap += (i->temp)
        length += 1
        println("Pass")
      }

      if(length>=maxLength){
          maxLength = length
      }

    }

     maxLength
  }
}

通过Map记录位置与length对应关系,通过Set记录哪些元素被访问过,使用prePose记录from侧位置,通过判断当前位置字符是否在Set中,更新prePose位置和length长度。代码整体并不复杂。

在提交leetcode过程中,能够实现AC,但执行时间较长。在讨论板块找到了简化版本,对其进行一定改动。这里附上。

import scala.collection.mutable.Map
object Solution {
    def lengthOfLongestSubstring(s: String) = {
    val map = Map[Char, Int]()
    var from = 0
    var length = 0
    var maxLength = 0
    var iper = 0
        
    for((char,to) <- s.zipWithIndex){
      map get char match{
        case None => maxLength = maxLength max(to - from + 1)
        case Some(i) => {
          // 如果重复字符位置较当前from位置靠近字符串首,不进行调整,否则对from位置进行更新
          if (i >= iper) {
            iper = i
          };
          from = from max (iper + 1);
          //确保保持maxLength更新
          length = to - from + 1
          if(length > maxLength){
            maxLength = length
          };
        }
      }
        map += (char->to)
    }
         maxLength
    }
 }

//使用Set版本,滑动窗口
import scala.collection.mutable
object Solution {
    def lengthOfLongestSubstring(s: String): Int = {
        var set = mutable.Set[Char]()
        var left = 0
        var right = 0
        var ans = 0

        while (right < s.length){
            val tempChar = s(right)
            if (set.contains(tempChar) == false){
                set += tempChar
                right += 1
            }
            else{
                while (left < right && set.contains(tempChar)){
                    set -= s(left)
                    left += 1
                    println("left: " + left)
                }
                set += tempChar
                right += 1
            }
            ans = Math.max(ans, right - left)
        }
        return ans
    }
}
func lengthOfLongestSubstring(s string) int {
    heap := map[byte]int{}
    res := 0
    for i, j:= 0, 0; i < len(s); i++ {
        heap[s[i]] += 1
        for (heap[s[i]] > 1) {
            heap[s[j]] -= 1
            j += 1
        }
        res = max(res, i-j+1)
    }
    return res 
}

func max(a int, b int) int {
    if (a > b) {
        return a
    } else {
        return b
    }
}

知识补充:

在对比两种实现过程中,了解到了zipWithIndex用法

计数器 -- zip或zipWithIndex方法自动创建一个计数器

1.可以通过for循环打印

for((char,to) <- s.zipWithIndex){
    println("char: " + char.toString + "    " + "to: " + to.toString)
 }
 
console:

char: a    to: 0
char: b    to: 1
char: c    to: 2
char: a    to: 3
char: b    to: 4
char: c    to: 5
char: b    to: 6
char: b    to: 7
  1. zip Stream 指定开始值

    for((char,to) <- s.zip(Stream from 1)){
           println("char: " + char.toString + "    " + "to: " + to.toString)
        }
        
    console:
    
    char: a    to: 1
    char: b    to: 2
    char: c    to: 3
    char: a    to: 4
    char: b    to: 5
    char: c    to: 6
    char: b    to: 7
    char: b    to: 8
    

    3.zipWithIndex有序集合

    当有序集合调用zipWithIndex的时候,它会返回一个有序的二元组集合,因为zipWithIndex是在一个已经存在的有序集合的基础上建立一个新的有序集合。

    val list = List("a", "b", "c")
    list.zipWithIndex
    
    console:
    
    List[(String, Int)] = List((a,0), (b,1), (c,2))
    
posted @ 2020-04-04 00:17  ganshuoos  阅读(126)  评论(0编辑  收藏  举报