26.删除有序数组中的重复项
题目
给你一个 非严格递增排列 的数组 nums
,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。然后返回 nums
中唯一元素的个数。
考虑 nums
的唯一元素的数量为 k
,你需要做以下事情确保你的题解可以被通过:
- 更改数组
nums
,使nums
的前k
个元素包含唯一元素,并按照它们最初在nums
中出现的顺序排列。nums
的其余元素与nums
的大小不重要。 - 返回
k
。
示例 1:
输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。
不需要考虑数组中超出新长度后面的元素。
示例 2:
输入:nums = [0,0,1,1,1,2,2,3,3,4] 输出:5, nums = [0,1,2,3,4] 解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。
代码
class Solution {public int removeDuplicates(int[] nums) {int slow = 0; //slow指向上一个插入的元素位置int fast = 0; //fast指向待比较的元素位置while(fast < nums.length){//当前待比较元素等于前一个插入元素,重复了if(nums[fast] == nums[slow]){fast++; //fast后移继续比较}//当前待比较元素不等于前一个插入元素else{nums[slow+1] = nums[fast]; //在slow后边插入新元素slow++; //slow加1继续指向新插入的元素为止fast++; //fast后移继续比较}}return slow+1; //slow指向的是上一个插入元素的位置,+1等于长度}
}
总结
核心是快慢指针,快指针进行遍历,指向带判断的元素,slow指向前一个被插入的元素,用于和fast进行比较。如果相同,fast往后走,如果不同,把fast插入slow+1位置,slow后移,fast后移。
283.移动零
题目
给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
请注意 ,必须在不复制数组的情况下原地对数组进行操作。
示例 1:
输入: nums =[0,1,0,3,12]
输出:[1,3,12,0,0]
示例 2:
输入: nums =[0]
输出:[0]
代码
class Solution {public void moveZeroes(int[] nums) {int slow = 0; //slow指向待插入元素的索引int fast = 0; //fast指向被判断的元素位置//fast遍历数组进行一个个判断是否为0while(fast < nums.length){//等于0,fast向后继续找if(nums[fast] == 0){fast++;}//不等于0,要插入元素else{nums[slow] = nums[fast]; //把fast元素插入slowslow++; //slow指向新的待插入元素位置fast++; //fast指向下一个带判断的元素位置}}//slow指向待插入元素位置,把[slow,nums.length)的补0while(slow < nums.length){nums[slow] = 0;slow++;}}
}
总结
核心还是fast和slow指针。fast指向带判断的元素,对nums进行遍历,slow指向待插入元素的位置。如果fast是0,fast++后移继续判断。如果fast不是0,就把fast插入slow,然后slow后移指向新的待插入元素位置,fast后移继续判断。最后,[slow,nums.length)的位置补0即可。
844.比较含退格的字符串
题目
给定 s
和 t
两个字符串,当它们分别被输入到空白的文本编辑器后,如果两者相等,返回 true
。#
代表退格字符。
注意:如果对空文本输入退格字符,文本继续为空。
示例 1:
输入:s = "ab#c", t = "ad#c" 输出:true 解释:s 和 t 都会变成 "ac"。
示例 2:
输入:s = "ab##", t = "c#d#" 输出:true 解释:s 和 t 都会变成 ""。
示例 3:
输入:s = "a#c", t = "b" 输出:false 解释:s 会变成 "c",但 t 仍然是 "b"
代码
class Solution {public boolean backspaceCompare(String s, String t) {String ss = remove(s); String tt = remove(t);return ss.equals(tt);}//remove函数用于把#退格处理掉,ab#c -> acpublic String remove(String s){//sb用于存储处理后的字符串StringBuilder sb = new StringBuilder();//遍历String字符串for(int i = 0;i < s.length();i++){char c = s.charAt(i); //获取第i个字符//如果不是#,加入sbif(c != '#'){sb.append(c);}//如果是#,要把sb最后一个元素删掉else{if(sb.length() != 0){ //防止sb长度为0,下标越界sb.deleteCharAt(sb.length()-1);}}}return sb.toString();}
总结
核心是把字符串的退格处理掉再用equals比较s和t。处理方法是,用StringBuild对象接收处理后的字符串,遍历String,如果不是#就加入sb,如果是#就把sb最后一个元素删除。
注意如果sb本身长度为0时,sb.deleteCharAt(sb.length()-1)可能导致下标-1越界,需要多个if处理。