zoukankan      html  css  js  c++  java
  • 记一次算法优化的过程

    最近在使用LeetCode:https://leetcode.com/

    顺道练习golang。

    今天下午完成了一个题目,原题如下:

    Longest Substring Without Repeating Characters:字符串最长的无重复字符的子字符串

    题目连接:https://leetcode.com/problems/longest-substring-without-repeating-characters/?tab=Description

    花了点时间熟悉了一下golang的字符串和slice的操作,

    主要用到了append方法,

    话说golang的数组和slice没有indexOf方法真是不方便。

    初步实现的算法是这样的:

    func lengthOfLongestSubstring(s string) int {
    	var length int = len(s)
    	temp := make([]byte, 0, length)
    	var curMax []byte
    	var curStartIndex int
    	for i := 0; i < length; i++ {
    		if len(temp) == 0 { //temp length == 0
    			curStartIndex = i
    			temp = append(temp, s[i])
    		} else if indexOf(temp, s[i]) == -1 { //temp not contains s[i]
    			temp = append(temp, s[i])
    		} else { //temp contains s[i]
    			if len(temp) > len(curMax) {
    				curMax = temp
    				fmt.Println("record:", string(temp))
    			}
    
    			i = curStartIndex
    			for len(temp) != 0 {
    				temp = temp[:0]
    			}
    
    		}
    
    	}
    	if curMax == nil || len(curMax) < len(temp) {
    		curMax = temp
    	}
    	return len(curMax)
    }
    
    func indexOf(a []byte, b byte) int {
    	var length = len(a)
    	for i := 0; i < length; i++ {
    		if a[i] == b {
    			return i
    		}
    	}
    	return -1
    }
    

      

    提交代码,耗时159ms,被81.58%的人打败了!!

    这尼玛我能忍?!!

    当前实现的算法是:

    记录当前子字符串的开始索引,

    拼接到无法拼接之后对比当前最大长度字符串的长度,

    然后从当前字符串的开始索引+1处又开始遍历。

    最差的情况下循环的次数为:

    len = 当前字符串长度

    次数 = len +(len-1)+...+1

    大概这么多次。

    于是仔细的想了想,有些啥可以优化的地方。

    其实在检测当前字符是否在当前字串中存在,

    如果重复了的话,

    可以得到当前字符在当前字串中的索引,

    那么,就不用重新从当前子字符串索引+1处开始循环,

    这里其实是多余的,

    只需要更新当前子串,更新子串开始索引即可。

    基本上循环len次就可以得出最长子串了。

    优化后代码如下:

    func lengthOfLongestSubstring(s string) int {
    
       var length int = len(s)
    
    	temp := make([]byte, 0, length)
    
    	var curMax []byte
    
    	var curStartIndex int
    
    	for i := 0; i < length; i++ {
    
    		if len(temp) == 0 { //temp length == 0
    
    			curStartIndex = i
    
    			temp = append(temp, s[i])
    
    		} else if indexOf(temp, s[i]) == -1 { //temp not contains s[i]
    
    			temp = append(temp, s[i])
    
    		} else { //temp contains s[i]
    
    			if len(temp) > len(curMax) {
    
    				curMax = temp
    
    			}
    
    			var index = indexOf(temp, s[i])
    
    			curStartIndex = curStartIndex + index + 1
    
    			temp = temp[index+1:]
    
    			temp = append(temp, s[i])
    
    		}
    
    
    
    	}
    
    	if curMax == nil || len(curMax) < len(temp) {
    
    		curMax = temp
    
    	}
    
    	return len(curMax)
    
    }
    
    
    
    func indexOf(a []byte, b byte) int {
    
    	var length = len(a)
    
    	for i := 0; i < length; i++ {
    
    		if a[i] == b {
    
    			return i
    
    		}
    
    	}
    
    	return -1
    
    }
    

    优化后打败了91.45%的人,耗时9ms。

      

    嗯, 可以接受。

  • 相关阅读:
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第九章画线】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第八章色彩】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第七章数学函数】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第六章函数】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第五章数组】
    量化投资_EasyLanguage/PowerLanguage教学课程__【第一篇基础】__【第四章跳跃字和保留字】
    常用简体汉字
    mongodb json序列化时间格式
    awk 改名
    ssh 免密码登录linux
  • 原文地址:https://www.cnblogs.com/adoontheway/p/6420142.html
Copyright © 2011-2022 走看看