题目: 给定一个排序数组,你需要在原地删除重复出现的元素,使得每个元素只出现一次,返回移除后数组的新长度。 不要使用额外的数组空间,你必须在原地修改输入数组并在使用o(1)额外空间的条件下完成。
我使用的是双指针法。快慢指针 C++思路: 这是一个给定排序数组,重复项是前后在一起的。那设置两个指针即慢指针i(初始为0),快指针j(初始为1)。 若nums[i] == nums[j] ,这就意味着出现重复元素,这里我是若前后指针所指元素不等时—直接i++,再用j覆盖i(跳过重复元素)。最后返回i+1。 *注意:别忘了,程序一开始时对数组为空时的条件判断。
class Solution { public: int removeDuplicates(vector<int>& nums) { if(nums.empty()) return 0; int i = 0; for(int j = 1;j < nums.size();++j){ if(nums[i] != nums[j]){ i++; nums[i] = nums[j]; } } return i+1; } };分割线-----------------------------------------------------------------------------------------------------------
题目: 给定一个数组,将数组中的元素向右移动k个位置,其中k是非负数。 给自己整了两种方法,欢迎大家一起讨论。
第一种方法是翻转。 c++思路: 1.考虑一下数组元素位置不会改变的情况? 1)数组长度=K; 2) 只有一个数组元素时 ;3)k=0 2.数组元素的最少移动情况? 首先,只要出现移动,那最少每个元素都移动一次; 其次,因为要在原地进行,所以必定需要暂存本次移动双方的数据; 最后,需要记录间隔为k的一轮移动完成的标识。 分界线--------------------------------- 1.c++的reverse(),格式reverse(&想要反转的起始元素,&想要反转的最后一个元素+1)。 2.(i+k)%size(nums) 作用1:当k要求旋转好几轮时,可通过%将其化简为只旋转1轮。 作用2:通过(i+k)%,可直接获取元素旋转之后的位置。
翻转法,经过三次翻转: 1.翻转0~(n-1) //先所有元素翻转 2.翻转0~(k-1) //翻转前k个元素 3.翻转k~(n-1) //翻转后k个元素 稍微理解一番还行,能够理解到位。 代码如下: 使用了使用C++自带的reverse函数
class Solution { public: void rotate(vector<int>& nums, int k) { int length = size(nums); k %= size(nums); reverse(&nums[0],&nums[length]); reverse(&nums[0],&nums[k]); reverse(&nums[k],&nums[length]); } };第二种方法是环形替换。 环形替换算法,有点难理解。 将要替换的元素保存在临时变量temp,向后替换第(k mod s)个元素,再循环向后,直到替换到最开始位置的元素。我再好好思考,先不贴码…
LeetCode初级算法(持续复盘)