力扣刷题[3、4] Go代码实现

代码Gitee:https://gitee.com/xiaoyinhui/golang-code/tree/develop/test-beego/tests


3. 无重复字符的最长子串

题目:

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

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

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

	// 提示:
	// 0 <= s.length <= 5 * 104
	// s 由英文字母、数字、符号和空格组成

	// 来源:力扣(LeetCode)
	// 链接:https://leetcode.cn/problems/longest-substring-without-repeating-characters
	// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法一:自己思路

func lengthOfLongestSubstring(s string) int {
	mMaxSubStrLen := 0
	mTempMax := 0
	mMap := make(map[byte]int)

	// 从当 i 的位置遍历到 s 的最后一个字符
	for i := 0; i < len(s); i++ {
		mChar := s[i]
		j, ok := mMap[mChar]
		if ok {
			// map 中存在这个字符,算字符长度
			if mTempMax > mMaxSubStrLen {
				mMaxSubStrLen = mTempMax
			}

			// 在从重复的地方,将其后面的数据重新计算
			i = j
			mTempMax = 0
			// 直接 make map 让系统自己回收之前的
			mMap = make(map[byte]int)
			continue
		}

		// map中没有字符将其加入
		mMap[mChar] = i
		// 子串长度+1
		mTempMax++
	}

	// 遍历完成后再次比较最大子串长度
	if mTempMax > mMaxSubStrLen {
		mMaxSubStrLen = mTempMax
	}

	return mMaxSubStrLen
}

方法二:看题解后的思路-滑动窗口

func lengthOfLongestSubstring2(s string) int {
	mMaxSubLen := 0
	mLeft := 0
	mRight := 0

	mMap := make(map[byte]int)
	// 右边的指针从1开始一直往后移动,直至 s 的最后一个字符
	for mRight < len(s) {
		mValue, ok := mMap[s[mRight]]
		if ok {
			// 计算一下当前的子串长度
			if mRight-mLeft > mMaxSubLen {
				mMaxSubLen = mRight - mLeft
			}

			// 左边的指针一直往右移动,一直到 mValue
			for mLeft <= mValue {
				// 删除map中重复字符左边所有的内容
				delete(mMap, s[mLeft])
				mLeft++
			}
		}

		// 每次只管往里面加就行,前面已经将重复的删除了
		mMap[s[mRight]] = mRight
		mRight++
	}

	// 遍历完成后再次计算最大子串长度
	if mRight-mLeft > mMaxSubLen {
		mMaxSubLen = mRight - mLeft
	}

	return mMaxSubLen
}

4. 寻找两个正序数组的中位数

题目:

	// 给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数。
	// 算法的时间复杂度应该为 O(log (m+n))。

	// 示例1:
	// 输入:nums1 = [1,3], nums2 = [2]
	// 输出:2.00000
	// 解释:合并数组 = [1,2,3] ,中位数 2

	// 示例2:
	// 输入:nums1 = [1,2], nums2 = [3,4]
	// 输出:2.50000
	// 解释:合并数组 = [1,2,3,4] ,中位数 (2 + 3) / 2 = 2.5

	// 提示:
	// nums1.length == m
	// nums2.length == n
	// 0 <= m <= 1000
	// 0 <= n <= 1000
	// 1 <= m + n <= 2000
	// -106 <= nums1[i], nums2[i] <= 106

	// 来源:力扣(LeetCode)
	// 链接:https://leetcode.cn/problems/median-of-two-sorted-arrays
	// 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

方法一:自己思路

func findMedianSortedArrays(nums1 []int, nums2 []int) float64 {

	mLen1 := len(nums1)
	mLen2 := len(nums2)
	mLen := mLen1 + mLen2
	mNewSliceCap := mLen/2 + 1
	mSlice := make([]int, 0, mNewSliceCap)
	a := 0
	b := 0
	mNum1 := math.MinInt
	mNum2 := math.MaxInt

	// 先将两个数组合并,合并长度达到中位数即可,然后取最后一位或者两位数计算中位数
	mCurrLen := 0
	for mCurrLen < mNewSliceCap {
		if a < mLen1 {
			mNum1 = nums1[a]
		} else {
			mNum1 = math.MinInt
		}

		if b < mLen2 {
			mNum2 = nums2[b]
		} else {
			mNum2 = math.MaxInt
		}

		if (mNum1 < mNum2) && (mNum1 > math.MinInt) {
			mSlice = append(mSlice, mNum1)
			a++
		} else {
			mSlice = append(mSlice, mNum2)
			b++
		}

		mCurrLen++
	}

	fmt.Println("两个数组总长度=", mLen, " 数组1长度=", mLen1, " 数组2长度=", mLen2)
	fmt.Println(mSlice, " Len=", len(mSlice), " cap=", cap(mSlice))

	mRet := float64(0)
	if mLen%2 == 0 {
		mRet = float64(mSlice[mCurrLen-1]+mSlice[mCurrLen-2]) / 2
	} else {
		mRet = float64(mSlice[mCurrLen-1])
	}
	fmt.Println("中位数=", mRet)

	return mRet
}

方法二:自己思路2

func findMedianSortedArrays2(nums1 []int, nums2 []int) float64 {
    mNewSliceCap := (len(nums1)+len(nums2))/2 + 1
    a := 0
    b := 0
    mNum1 := math.MinInt
    mNum2 := math.MaxInt
    mIsTwoNum := (len(nums1)+len(nums2))%2 == 0
    m := float64(0)
    n := float64(0)

    // 直接遍历两个数组,遍历到中位数的地方,然后判断,用两个参数接收中位数,根据两个数组长度和判断奇偶后计算中位数
    mCurrLen := 0
    for mCurrLen < mNewSliceCap {
        if a < len(nums1) {
            mNum1 = nums1[a]
        } else {
            mNum1 = math.MinInt
        }

        if b < len(nums2) {
            mNum2 = nums2[b]
        } else {
            mNum2 = math.MaxInt
        }

        if (mNum1 < mNum2) && (mNum1 > math.MinInt) {
            if mIsTwoNum {
                if mCurrLen+2 == mNewSliceCap {
                    m = float64(mNum1)
                }
                if mCurrLen+1 == mNewSliceCap {
                    n = float64(mNum1)
                }
            } else {
                if mCurrLen+1 == mNewSliceCap {
                    m = float64(mNum1)
                }
            }
            a++
        } else {
            if mIsTwoNum {
                if mCurrLen+2 == mNewSliceCap {
                    m = float64(mNum2)
                }
                if mCurrLen+1 == mNewSliceCap {
                    n = float64(mNum2)
                }
            } else {
                if mCurrLen+1 == mNewSliceCap {
                    m = float64(mNum2)
                }
            }
            b++
        }

        mCurrLen++
    }

    if mIsTwoNum {
        return (m + n) / 2
    } else {
        return m
    }
}

一点点笔记,以便以后翻阅。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小印丶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值