leetcode算法 -- 数组

news2024/12/28 18:14:50

1 数组

常见的数组算法有双指针,滑动窗口,二分查找和分冶。

2 双指针

核心的思路:使用两个指针,一个从头开始索引,一个从尾开始索引。

2.1 两数之和ii 167

给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target 的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 < index2 <= numbers.length 。
以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。

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

思路:num1+num2=target;数组按照非递增顺序进行排列;
num1从最小的数开始,num2从最大的数开始,根据两数之和和target的关系,移动两个指针;

Algorithm TwoSum(nums, target):
    Input: A list of numbers "nums" and a target number "target"
    Output: A list of two indices

    i <- 0
    j <- length(nums) - 1

    while j > i do  // 没有重复元素
        val <- nums[i] + nums[j]

        if val > target then
            j <- j - 1
        else if val < target then
            i <- i + 1
        else
            return [i, j]

    return []

2.2 反转字符串中的元音字母 345

给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现不止一次。
用两个指针从头和尾开始索引

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

Algorithm ReverseVowels(strs):
    Input: A string "strs"
    Output: A string with its vowels reversed

    i <- 0
    j <- length(strs) - 1

    while j > i do
        while !findVowel(strs[i]) do
            i <- i + 1
        end while
        while !findVowel(strs[j]) do
            j <- j - 1
        end while
        swap(strs, i, j)
        i <- i + 1
        j <- j - 1
    end while

    return strs

2.3 移除元素 27

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。

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

思路1:头尾用两个指针,找到合适的,就发生交换,最后右指针的位置。

Algorithm MoveTargetToFront(nums, target):
    Input: A list of numbers "nums" and a target number "target"
    Output: An integer representing the final index 'j' incremented by 1

    i <- 0
    j <- length(nums) - 1

    while j > i do
        if nums[i] == target then
            swap(nums, i, j)
            i <- i + 1
            j <- j - 1
        else 
            i <- i + 1
        end if
    end while

    return j + 1

2.4 删除重复元素

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums 中唯一元素的个数。
考虑 nums 的唯一元素的数量为 k ,你需要做以下事情确保你的题解可以被通过:
更改数组 nums ,使 nums 的前 k 个元素包含唯一元素,并按照它们最初在 nums 中出现的顺序排列。nums 的其余元素与 nums 的大小不重要。
返回 k 。

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

思路:用指针i,迭代索引数组,用指针k从0开始记录没有重复的数据

Algorithm MoveTargetToFront(nums, target):
    Input: A list of numbers "nums" and a target number "target"
    Output: An integer representing the final index 'j' incremented by 1
k <- 1
pre = INT_MIN  // 一个技巧,防止首数字重复
for i <- 0 to n - 1 do
    if nums[i] != pre then
        nums[k] <- nums[i]
        pre = nums[i]
        k <- k + 1
    endif
endfor
return k

2.5 三数之和 (3Sum) 15

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请
你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。

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

思路:将三数之和转换成两数之和,然后在用两个指针,一左一右进行迭代搜索。

for i <- 0 to n - 3 do
    if nums[i] > 0 then
        break
    endif
    
    j <- i + 1
    k <- n - 1
    
    while k > j do
        if nums[i] + nums[j] + nums[k] > 0 then
            k <- k - 1
        else if nums[i] + nums[j] + nums[k] < 0 then
            j <- j + 1
        else if nums[i] + nums[j] + nums[k] == 0 then
            result.push_back({i, j, k})
            j <- j + 1
  			k <- k - 1
  			// 有重复的内容,进行迭代更新
			while nums[j] == nums[j - 1] do
				j <- j + 1 
			while nums[k] = nums[k + 1] do
				k <- k - 1 
        endif
    endwhile
endfor

2.6 盛最多水的容器11

给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。

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

思路:

left <- 0
right <- n - 1
max_area <- 0

while right > left do
    area <- (right - left) * max(nums[left], nums[right])
    
    if area > max_area then
        max_area <- area
    endif
    
    if nums[left] > nums[right] then
        right <- right - 1
    else
        left <- left + 1
    endif
endwhile

return max_area

2.7 两数之和 (Two Sum)1

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。

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

思路1:先将nums按照递增进行排序,然后用左右两个指针;
思路2:通过unordered_map<int, int>记录已经索引过的数字,在迭代的过程中,看看有没有索引过的项。

2.8 反转字符串 II (Reverse String II) 541

给定一个字符串 s 和一个整数 k,从字符串开头算起,每计数至 2k 个字符,就反转这 2k 字符中的前 k 个字符。
如果剩余字符少于 k 个,则将剩余字符全部反转。
如果剩余字符小于 2k 但大于或等于 k 个,则反转前 k 个字符,其余字符保持原样。

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

思路:将 i ∈ [ 0 , k − 1 ] i \in [0,k-1] i[0,k1] 进行reverse; i ∈ [ k , 2 k − 1 ] i \in [k, 2k-1] i[k,2k1]不进行调整;

// 通过step: 2k,防止最后一段处理不了
for i <- 0 to n - 1 step 2k do
    reverse(str.begin() + i, str.begin() + i + min(k, n - 1 - i))
endfor

2.9 回文字符串 II (Valid Palindrome II)680

给你一个字符串 s,最多 可以从中删除一个字符。
请你判断 s 是否能成为回文字符串:如果能,返回 true ;否则,返回 false 。

思路:
通过递归来处理,check(s, i, k, time),不仅可以处理删除一个,可以处理删除k个

bool ValidPalindrome(s)
    result = check(s, 0, n-1, 1) // 可以错误一次
    return result

bool check(s, i, j, time)
    while (i < j)
        if (s[i] != s[j])
            return time > 0 || check(s, i, j-1, time--) || check(s, i + 1, j, time--)
        endif
        i++
        j--
    endwhile

3 滑动窗口

滑动窗口(Sliding Window)是一种常见的算法策略,主要用于解决数组/链表的子元素问题,如求解子数组的最大和、子数组的最小长度等。

Algorithm SlidingWindowAlgorithm(arr, target):
    Input: An array of integers arr, and a target integer target
    Output: The desired subarray or length or sum etc.

    left <- 0 // initialize left pointer
    right <- 0 // initialize right pointer
    windowSum <- 0 // initialize the sum of the window
    minLength <- inf // initialize the length of the minimum subarray
    result <- []

    while right is less than length of arr do:
        // expand the right boundary of the window
        windowSum <- windowSum + arr[right]
        right <- right + 1

        // shrink the window from the left
        while windowSum is greater than target do:
            minLength <- min(minLength, right - left) 
            windowSum <- windowSum - arr[left]
            left <- left + 1

        if windowSum equals to target then
            result.push(subarray from left to right-1)
            windowSum <- windowSum - arr[left]
            left <- left + 1
    return result or minLength

3.1 最大子序和 (Maximum Subarray) 53

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。
子数组 是数组中的一个连续部分。

思路:技巧:如何累加的结果比0小,那么就重新开始累加

Algorithm MaximumSubarraySum(nums):
    Input: An array of integers nums
    Output: Maximum subarray sum

    res <- 0 // initialize the current subarray sum
    sum <- 0 // initialize the maximum subarray sum
	// 处理特殊情况,如果最大的数没有0大怎么办
	res <- INT_MIN
	for i from 0 to n-1 do:
		res <- max(res, nums[i])
	endfor
	
	if res <= 0 then
		return res;
	endif
	
    for i from 0 to n-1 do:
        res <- res + nums[i]
        res <- max(0, res)
        sum <- max(sum, res)
    endfor

    return sum

3.2 和为K的子数组 (Subarray Sum Equals K) 560

思路:将和存在unordered_map<int, int>中,在索引的时候,通过在unordered_map的进行搜索
在这里插入图片描述

um <- unordered_map<int, int>()
sum <- 0
um[0] <- 1
count <- 0

for i from 0 to n-1 do
    sum <- sum + nums[i]
    
    if um.find(sum - target) != um.end() then
        count <- count + um[sum - target]
    
    um[sum] <- um[sum] + 1
endfor

3.4 长度最小的子数组 (Minimum Size Subarray Sum) 209

思路:这里有个技巧,找到长度最小的子数组后,继续往后搜索

l_sum
r_sum
min_len = n - 1
for i from 0 to n-1 do
	r_sum <- r_sum + nums[i]
	while r_sum - l_sum < k do
		if (j - r + 1 < min_len) then
			min_len = r - l + 1		
		endif
		l_sum <- l_sum + nums[j++]
	endwhile
endfor

在这里插入图片描述

3.5 滑动窗口最大值 (Sliding Window Maximum) 239

思路:
1)通过map得到最大值;
map.rbegin()->first
2)通过++um[num[i]]进行滑动记录,删除不需要的内容

map<int, int>um;
int k = min(n, k)
for i from 0 to k-1 do 
	++um[nums[i]];
endfor
res.push_back(um->rbegin()->first)
for i from k to n - 1 do
	if --um[i - k] == 0 then
		um.erase(nums[i - k])
	endif
	++um[i];	
	res.push_back(um->rbegin()->first)
endfor

在这里插入图片描述

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

给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
关键的是要实时更新最左边的数据

unordered_map<char, int> um
max_len <- 0
l <- 0
for r from 0 to n-1 do
	if um.find(s[r]) != um.end() then
		if um[s[r]] >= l then 
			l <- um[s[r]] + 1
		endif 
		len <- r - l + 1
		if len > max_len then
			max_len <- len
		endif
	endif
	um[s[r]] = r
endfor

3.8 和为K的最长子数组长度1493

给你一个二进制数组 nums ,你需要从中删掉一个元素。
请你在删掉元素的结果数组中,返回最长的且只包含 1 的非空子数组的长度。
如果不存在这样的子数组,请返回 0 。

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/longest-subarray-of-1s-after-deleting-one-element
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

思路:
使用两个指针,l 从左边迭代到最右边,r 遇到两次0停下来, l 从零开始

for l from 0 to n-1 do
	cnt <- 0
	while s[r++] == '0' then
		cnt <- cnt + 1	
	endwhile
	while cnt > 1 then
		if s[r++] == '0'
			cnt <- cnt - 1
	endwhile
	max_len <- max(max_len, r - l - 1)	
endfor

3.9 连续的子数组和 523

给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:
子数组大小 至少为 2 ,且
子数组元素总和为 k 的倍数。
如果存在,返回 true ;否则,返回 false 。
如果存在一个整数 n ,令整数 x 符合 x = n * k ,则称 x 是 k 的一个倍数。0 始终视为 k 的一个倍数。

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

思路:
两个相同部分的余数相减的结果是K的倍数。

unordered_map<int, int> um;
sum <- 0
for i from 0 to n-1 do
	sum <- (sum + nums[i]) % k
	if um.find(sum) != um.end() then
		return tru;	
	endif
	um[sum] = i
endfor
return false

在这里插入图片描述

3.10 替换后的最长重复字符 424

给你一个字符串 s 和一个整数 k 。你可以选择字符串中的任一字符,并将其更改为任何其他大写英文字符。该操作最多可执行 k 次。
在执行上述操作后,返回包含相同字母的最长子字符串的长度。

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

思路:
1)r从0到n-1开始迭代,每次迭代过程中,找到合适的l,满足要求。如果大于要求,就去迭代更新了.
2)用前缀的unordered_map记录字符出现的次数

unordered_map<int, int> um
for r from 0 to n-1 do
	++um[nums[r] - 'A']
           int maxIndex = (std::max_element(um.begin(), um.end())
           if r - l + 1 - um[maxIndex] > k then
           		--um[s[l++] - 'A']
           endif
           if r- l + 1 > max_len then
           	max_len <- r - l + 1
           endif                                 
endfor 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/660930.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能python:Python怎么随机生成一个数

Python怎么随机生成一个数 在Python编程中&#xff0c;经常有需要随机生成一个整数的需求&#xff0c;比如在游戏中生成随机的道具&#xff0c;或者在数据分析中进行随机采样。 Python中提供了一个内置的random模块&#xff0c;可以方便地实现随机生成一个数。 使用random模…

【Windows】虚拟串口工具VSPD6.9安装

【Windows】虚拟串口工具VSPD6.9安装 1、背景2、安装3、补丁4、验证5、下载 1、背景 参考【Windows】虚拟串口工具VSPD7.2安装。 本博客安装的版本是VSPD6.9&#xff0c;并在文末留下下载链接&#xff0c;以供学习研究。 虚拟串口工具一般用来做上位机软件的串口通信调试&…

Java性能权威指南-总结14

Java性能权威指南-总结14 堆内存最佳实践对象生命周期管理对象重用 堆内存最佳实践 对象生命周期管理 在很大程度上&#xff0c;Java会尽量减轻开发者投入到对象生命周期管理上的精力&#xff1a;开发者在需要的时候创建对象&#xff0c;当不再需要这些对象时&#xff0c;它们…

C++11新特性之右值引用

目录 前文 一&#xff0c;什么是右值引用&#xff1f; 二&#xff0c;左值引用和右值引用比较 三&#xff0c;右值引用的应用场景以及作用 四&#xff0c; 右值引用左值的场景分析 五&#xff0c;完美转发 总结 前文 在C98标准后&#xff0c;C11标准的更新为C注入了新活力&…

chatgpt赋能python:Python如何生成100个随机整数

Python如何生成100个随机整数 在Python中&#xff0c;我们可以使用random库来生成随机整数。在本文中&#xff0c;我们将介绍如何使用Python生成100个随机整数。 什么是随机整数 随机整数是指在一定范围内&#xff0c;产生的整数是随机的且不重复的。这在数据分析、机器学习…

2. CSS的元素显示模式

了解元素的显示模式可以更好的让我们布局页面. 1.什么是元素的显示模式 2.元素显示模式的分类 3.元素显示模式的转换 2.1什么是元素显示模式 作用:网页的标签非常多&#xff0c;在不同地方会用到不同类型的标签&#xff0c;了解他们的特点可以更好的布局我们的网页。 元素显示…

chatgpt赋能python:如何在Python中创建模块:完整指南

如何在Python中创建模块&#xff1a;完整指南 如果你是一位Python开发者&#xff0c;你肯定需要用到模块。模块使得代码更容易组织和管理&#xff0c;并且可以复用许多代码片段&#xff0c; 提高代码的可重用性。在Python中&#xff0c;模块是一组相关函数&#xff0c;方法和变…

[论文笔记]End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF

引言 本文是论文End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF的阅读笔记。 本论文提出了一个受益于单词级(word)和字符级(character)表示的网络架构,通过组合双向LSTM,CNN和CRF。 简介 首先通过CNN编码一个单词的字符级信息到相应的字符表征。然后组合…

【C数据结构】动态顺序表_SeqList

目录 【1】数据结构概述 【1.1】什么是数据结构&#xff1f; 【1.2】数据结构分类 【1.3】数据结构术语 【2】数据结构特点 【2】动态顺序表 【2.1】动态顺序表定义数据结构和接口 【2.1】动态顺序表创建初始化 【2.2】动态顺序表初始化 【2.3】动态顺序表内存释放 【…

【Express.js】处理请求数据

处理请求数据 本节将具体介绍express后端处理请求源携带数据的一些方法和技巧 动态路径 很多时候我们需要处理一些类似但有操作差别或不同对象的业务&#xff0c;我们可以监听一段基本路径&#xff0c;将其中某一个段或者某几段路径作为变量&#xff0c;在接口中根据不同的路…

大学计算机专业实习心得报告13篇

大学计算机专业实习心得报告&#xff08;篇1&#xff09; 通过理论联系实际&#xff0c;巩固所学的知识&#xff0c;提高处理实际问题的能力&#xff0c;为顺利毕业进行做好充分的准备&#xff0c;并为自己能顺利与社会环境接轨做准备。通过这次实习&#xff0c;使我们进一步理…

chatgpt赋能python:如何用Python创建优秀的项目

如何用Python创建优秀的项目 Python是一种功能强大的编程语言&#xff0c;可用于创建各种不同类型的项目。本文将介绍如何使用Python创建优秀的项目&#xff0c;并包括一些有用的技巧和工具。在本文中&#xff0c;我们将着重讨论如何优化我们的Python项目以获得更好的SEO排名。…

Gitlab 服务器搭建

引言 GitLab 是一个用于仓库管理系统的开源项目&#xff0c;使用Git作为代码管理工具&#xff0c;并在此基础上搭建起来的Web服务。安装方法是参考GitLab在GitHub上的Wiki页面。Gitlab是被广泛使用的基于git的开源代码管理平台, 基于Ruby on Rails构建, 主要针对软件开发过程中…

C语言:求输入的两个数的最小公倍数

题目&#xff1a; 求输入的两个数的最小公倍数 思路一&#xff1a;普通方法 &#xff08;思路简单&#xff0c;效率较低&#xff09; 总体思路&#xff1a; &#xff08;一&#xff09;. 输入两个数&#xff1a;a 和 b&#xff0c; 使用 三目表达式 把较大值 取出 &#xff…

[元带你学: eMMC协议详解 17] eMMC 安全方案 之 RPMB(Replay Protected Memory Block 重放保护内存块)

依JEDEC eMMC 5.1及经验辛苦整理&#xff0c;付费内容&#xff0c;禁止转载。 所在专栏 《元带你学: eMMC协议详解》 内容摘要 全文 6300 字&#xff0c; 主要内容有 目录 1 概念 2 容量大小 3 重放保护的原理 4 不同访问类型流程 4.1. 写认证密钥&#xff08;write Au…

coder oss 真正私有化部署的云端开发环境,nas也可以装

先看效果&#xff1a; 主界面&#xff0c;显示了你有那些工作空间 某个工作空间&#xff0c;我这里集成了web版vscode&#xff0c;也可以使用本地的vscode和其他开发IDE 有独立的终端和集成webide 以后就可以一个ipad都可以写代码了&#xff1b; 下面是平台搭建过程&#xff0…

C语言入门基础知识(万字笔记)

一、前言部分 本篇文章&#xff0c;将会主要介绍c语言的基本数据类型、基本运算符、语句&#xff0c;三大结构、数组、指针、宏定义等内容 二、具体部分 1、基本数据类型 1、基本数据类型 在C语言中&#xff0c;承载一系列信息的数字或中字符都属于数据类型&#xff0c;计算…

产品设计.B端产品vsC端产品

一、用户群体 01、B端&#xff1a;一般是多角色群体、多维度&#xff0c;一般是3个维度&#xff0c;决策者&#xff08;老板&#xff09;、管理者&#xff08;财务、业务部门负责人&#xff09;和执行者&#xff08;使用的用户&#xff09;。 02、C端&#xff1a;群体相对单一…

K8s 中 port, targetPort, NodePort的区别

看1个例子&#xff1a; 我们用下面命令去创建1个pod2&#xff0c; 里面运行的是1个nginx kubectl create deployment pod2 --imagenginx当这个POD被创建后&#xff0c; 其实并不能被外部访问&#xff0c; 因为端口映射并没有完成. 我们用下面这个命令去创建1个svc &#xff…

msvcp140.dll是什么?怎么解决电脑提示msvcp140.dll丢失的问题?(分享解决方法)

msvcp140.dll是动态链接库文件&#xff0c;是一种不可执行的二进制程序文件&#xff0c;允许程序共享执行特殊任务所需要的代码和其他资源。程序可根据DLL文件中的指令打开、启用、查询、禁用和关闭驱动程序。 很多小伙伴在使用电脑软件的时候&#xff0c;有一些问题会搞不明白…