2026-06-07合并相邻且相等的元素。用go语言给你一个整数数组 nums。你要反复做合并直到再也找不到可以合并的相邻相等元素为止。规则是在当前数组里只要存在某两个相邻位置上的值相同就可以进行合并。每次操作时要优先挑选“最靠左”的那一对相邻相等元素把这两个数用它们的和替换掉。完成一次合并后数组长度会减少 1然后继续在新数组上寻找相邻相等的最左那一对重复此过程直到无法再合并。最终返回合并完成后的数组。1 nums.length 100000。1 nums[i] 100000。输入 nums [3,1,1,2]。输出 [3,4]。解释中间的两个元素相等将它们合并为 1 1 2结果为 [3, 2, 2]。最后的两个元素相等将它们合并为 2 2 4结果为 [3, 4]。不再存在相邻且相等的元素。因此答案为 [3, 4]。题目来自力扣3834。过程分步详解一、核心规则回顾每次必须找当前数组中最靠左的一对相邻相等元素合并合并方式两个相等数替换为它们的和即数值×2数组长度-1合并后重新遍历新数组继续找最左侧可合并对直到无相邻相等元素为止。二、完整执行过程分步详细描述初始状态原始数组[3, 1, 1, 2]长度4当前无任何合并操作开始第一次查找。第一步查找并合并「最左侧相邻相等元素」从数组左到右依次检查相邻元素第1个元素3和第2个元素1不相等跳过第2个元素1和第3个元素1相等这是当前最左侧的可合并对。执行合并两个1相加 2替换这两个元素合并后新数组[3, 2, 2]长度变为3第二步在新数组中重新查找「最左侧相邻相等元素」合并后必须从头开始检查新数组从左到右依次检查第1个元素3和第2个元素2不相等跳过第2个元素2和第3个元素2相等这是当前最左侧的可合并对。执行合并两个2相加 4替换这两个元素合并后新数组[3, 4]长度变为2第三步最终检查无可用合并检查最终数组[3, 4]唯一一对相邻元素3和4不相等没有可合并的元素合并流程结束。最终结果合并完成后的数组[3, 4]三、代码实现的核心逻辑文字描述代码用了**栈切片模拟栈**的高效思路替代了「反复遍历数组」的低效方式完美匹配题目规则初始化一个空栈复用原数组空间不额外开辟大内存遍历原始数组的每一个数字把当前数字准备入栈检查栈顶元素如果栈顶和当前数字相等就弹出栈顶元素当前数字翻倍等价于合并重复检查直到栈顶和当前数字不相等再把当前数字入栈遍历结束后栈中剩余的元素就是最终合并完成的数组。这个逻辑**自动实现了「优先合并最左侧」**的规则且无需反复遍历数组。四、时间复杂度 额外空间复杂度1. 总时间复杂度O(n)n是输入数组的长度每个元素最多入栈1次、出栈1次没有嵌套循环所有操作都是线性的即使数组长度达到上限10^5也能高效运行。2. 总额外空间复杂度O(1)代码复用了原数组的内存空间st : nums[:0]没有创建新的大容量切片仅使用了几个临时变量循环变量、栈长度等占用空间是固定的不随输入数组长度变化最终返回的数组也没有开辟新内存是通过指针转换直接复用原空间属于原地操作。总结合并过程先合并中间的112得到[3,2,2]再合并224得到最终结果[3,4]时间复杂度O(n)线性时间高效处理十万级数据额外空间复杂度O(1)原地操作几乎不占用额外内存。Go完整代码如下packagemainimport(fmtunsafe)funcmergeAdjacent(nums[]int)[]int64{st:nums[:0]// 原地for_,x:rangenums{forlen(st)0st[len(st)-1]x{stst[:len(st)-1]x*2}stappend(st,x)}// 力扣的 int 就是 int64直接 O(1) 转成 []int64return*(*[]int64)(unsafe.Pointer(st))}funcmain(){nums:[]int{3,1,1,2}result:mergeAdjacent(nums)fmt.Println(result)}Python完整代码如下# -*-coding:utf-8-*-fromtypingimportListdefmerge_adjacent(nums:List[int])-List[int]: 原地合并相邻的相同数字类似 2048 游戏规则 将相邻且相同的数字合并为它们的和乘以2 st[]# 使用列表作为栈forxinnums:# 当栈不为空且栈顶元素等于当前元素时进行合并whilestandst[-1]x:st.pop()# 移除栈顶元素x*2# 当前元素翻倍st.append(x)returnstdefmain():nums[3,1,1,2]resultmerge_adjacent(nums)print(result)if__name____main__:main()C完整代码如下#includeiostream#includevector#includecstdintusingnamespacestd;vectorint64_tmergeAdjacent(vectorintnums){// 原地操作使用 nums 的前部作为栈空间size_t stackSize0;// 栈的大小for(intx:nums){// 当栈不为空且栈顶元素等于当前元素时进行合并while(stackSize0nums[stackSize-1]x){stackSize--;// 弹出栈顶x*2;// 当前元素翻倍}// 将当前元素放入栈中nums[stackSize]x;stackSize;}// 将结果转换为 int64_t 类型的 vectorvectorint64_tresult;result.reserve(stackSize);for(size_t i0;istackSize;i){result.push_back(nums[i]);}returnresult;}intmain(){vectorintnums{3,1,1,2};vectorint64_tresultmergeAdjacent(nums);cout[;for(size_t i0;iresult.size();i){if(i0)cout ;coutresult[i];}cout]endl;return0;}
2026-06-07:合并相邻且相等的元素。用go语言,给你一个整数数组 nums。你要反复做合并,直到再也找不到可以合并的相邻相等元素为止。 规则是:在当前数组里,只要存在某两个相邻位置上的值相同,
2026-06-07合并相邻且相等的元素。用go语言给你一个整数数组 nums。你要反复做合并直到再也找不到可以合并的相邻相等元素为止。规则是在当前数组里只要存在某两个相邻位置上的值相同就可以进行合并。每次操作时要优先挑选“最靠左”的那一对相邻相等元素把这两个数用它们的和替换掉。完成一次合并后数组长度会减少 1然后继续在新数组上寻找相邻相等的最左那一对重复此过程直到无法再合并。最终返回合并完成后的数组。1 nums.length 100000。1 nums[i] 100000。输入 nums [3,1,1,2]。输出 [3,4]。解释中间的两个元素相等将它们合并为 1 1 2结果为 [3, 2, 2]。最后的两个元素相等将它们合并为 2 2 4结果为 [3, 4]。不再存在相邻且相等的元素。因此答案为 [3, 4]。题目来自力扣3834。过程分步详解一、核心规则回顾每次必须找当前数组中最靠左的一对相邻相等元素合并合并方式两个相等数替换为它们的和即数值×2数组长度-1合并后重新遍历新数组继续找最左侧可合并对直到无相邻相等元素为止。二、完整执行过程分步详细描述初始状态原始数组[3, 1, 1, 2]长度4当前无任何合并操作开始第一次查找。第一步查找并合并「最左侧相邻相等元素」从数组左到右依次检查相邻元素第1个元素3和第2个元素1不相等跳过第2个元素1和第3个元素1相等这是当前最左侧的可合并对。执行合并两个1相加 2替换这两个元素合并后新数组[3, 2, 2]长度变为3第二步在新数组中重新查找「最左侧相邻相等元素」合并后必须从头开始检查新数组从左到右依次检查第1个元素3和第2个元素2不相等跳过第2个元素2和第3个元素2相等这是当前最左侧的可合并对。执行合并两个2相加 4替换这两个元素合并后新数组[3, 4]长度变为2第三步最终检查无可用合并检查最终数组[3, 4]唯一一对相邻元素3和4不相等没有可合并的元素合并流程结束。最终结果合并完成后的数组[3, 4]三、代码实现的核心逻辑文字描述代码用了**栈切片模拟栈**的高效思路替代了「反复遍历数组」的低效方式完美匹配题目规则初始化一个空栈复用原数组空间不额外开辟大内存遍历原始数组的每一个数字把当前数字准备入栈检查栈顶元素如果栈顶和当前数字相等就弹出栈顶元素当前数字翻倍等价于合并重复检查直到栈顶和当前数字不相等再把当前数字入栈遍历结束后栈中剩余的元素就是最终合并完成的数组。这个逻辑**自动实现了「优先合并最左侧」**的规则且无需反复遍历数组。四、时间复杂度 额外空间复杂度1. 总时间复杂度O(n)n是输入数组的长度每个元素最多入栈1次、出栈1次没有嵌套循环所有操作都是线性的即使数组长度达到上限10^5也能高效运行。2. 总额外空间复杂度O(1)代码复用了原数组的内存空间st : nums[:0]没有创建新的大容量切片仅使用了几个临时变量循环变量、栈长度等占用空间是固定的不随输入数组长度变化最终返回的数组也没有开辟新内存是通过指针转换直接复用原空间属于原地操作。总结合并过程先合并中间的112得到[3,2,2]再合并224得到最终结果[3,4]时间复杂度O(n)线性时间高效处理十万级数据额外空间复杂度O(1)原地操作几乎不占用额外内存。Go完整代码如下packagemainimport(fmtunsafe)funcmergeAdjacent(nums[]int)[]int64{st:nums[:0]// 原地for_,x:rangenums{forlen(st)0st[len(st)-1]x{stst[:len(st)-1]x*2}stappend(st,x)}// 力扣的 int 就是 int64直接 O(1) 转成 []int64return*(*[]int64)(unsafe.Pointer(st))}funcmain(){nums:[]int{3,1,1,2}result:mergeAdjacent(nums)fmt.Println(result)}Python完整代码如下# -*-coding:utf-8-*-fromtypingimportListdefmerge_adjacent(nums:List[int])-List[int]: 原地合并相邻的相同数字类似 2048 游戏规则 将相邻且相同的数字合并为它们的和乘以2 st[]# 使用列表作为栈forxinnums:# 当栈不为空且栈顶元素等于当前元素时进行合并whilestandst[-1]x:st.pop()# 移除栈顶元素x*2# 当前元素翻倍st.append(x)returnstdefmain():nums[3,1,1,2]resultmerge_adjacent(nums)print(result)if__name____main__:main()C完整代码如下#includeiostream#includevector#includecstdintusingnamespacestd;vectorint64_tmergeAdjacent(vectorintnums){// 原地操作使用 nums 的前部作为栈空间size_t stackSize0;// 栈的大小for(intx:nums){// 当栈不为空且栈顶元素等于当前元素时进行合并while(stackSize0nums[stackSize-1]x){stackSize--;// 弹出栈顶x*2;// 当前元素翻倍}// 将当前元素放入栈中nums[stackSize]x;stackSize;}// 将结果转换为 int64_t 类型的 vectorvectorint64_tresult;result.reserve(stackSize);for(size_t i0;istackSize;i){result.push_back(nums[i]);}returnresult;}intmain(){vectorintnums{3,1,1,2};vectorint64_tresultmergeAdjacent(nums);cout[;for(size_t i0;iresult.size();i){if(i0)cout ;coutresult[i];}cout]endl;return0;}