27.移除元素
问题:给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。
不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。
元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
示例:
输入:nums = [3,2,2,3], val = 3
输出:2, nums = [2,2]
解释:函数应该返回新的长度 2, 并且 nums 中的前两个元素均为 2。你不需要考虑数组中超出新长度后面的元素。例如,函数返回的新长度为 2 ,而 nums = [2,2,3,3] 或 nums = [2,2,0,0],也会被视作正确答案。
输入:nums = [0,1,2,2,3,0,4,2], val = 2
输出:5, nums = [0,1,4,0,3]
解释:函数应该返回新的长度 5, 并且 nums 中的前五个元素为 0, 1, 3, 0, 4。注意这五个元素可为任意顺序。你不需要考虑数组中超出新长度后面的元素。
思路:快慢指针
如果 fast
遇到需要去除的元素,则直接跳过,否则就告诉 slow
指针,并让 slow
前进一步。图解如下:参考代码随想录
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0, fast = 0;
while(fast < nums.length){
if(nums[fast] != val){
nums[slow] = nums[fast];
slow++;
}
fast++;
}
return slow;
}
}
283.移动零
问题:给定一个数组 nums
,编写一个函数将所有 0
移动到数组的末尾,同时保持非零元素的相对顺序。
示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
思路:快慢指针
与上一题思路一样,发现0
的话,慢指针slow
不动,快指针fast
往前走,直到fast
指向的元素不为0
,然后交换快慢指针的值,将0不断的向后移。
class Solution {
public void moveZeroes(int[] nums) {
int slow = 0, fast = 0;
while(fast < nums.length){
if(nums[fast] != 0){
int temp = nums[slow];
nums[slow] = nums[fast];
nums[fast] = temp;
slow++;
}
fast++;
}
}
}
844.比较含退格的字符串
问题:给定 s 和 t 两个字符串,当它们分别被输入到空白的文本编辑器后,请你判断二者是否相等。# 代表退格字符。
如果相等,返回 true ;否则,返回 false 。
注意:如果对空文本输入退格字符,文本继续为空。
示例:
输入:s = "ab#c", t = "ad#c"
输出:true
解释:S 和 T 都会变成 “ac”。
输入:s = "ab##", t = "c#d#"
输出:true
解释:s 和 t 都会变成 “”。
输入:s = "a##c", t = "#a#c"
输出:true
解释:s 和 t 都会变成 “c”。
输入:s = "a#c", t = "b"
输出:false
解释:s 会变成 “c”,但 t 仍然是 “b”。
思路:栈,
匹配问题首先想到的就是栈
遇到'#'
将栈顶元素出栈,最后比较两个栈中的元素即可
class Solution {
public boolean backspaceCompare(String s, String t) {
Stack<Character> stack1 = new Stack();
Stack<Character> stack2 = new Stack();
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
if(c == '#' && !stack1.isEmpty()){
stack1.pop();
} else {
stack1.push(c);
}
}
for(int i = 0; i < t.length(); i++){
char c = t.charAt(i);
if(c == '#' && !stack2.isEmpty()){
stack2.pop();
} else {
stack2.push(c);
}
}
if(stack1.size() != stack2.size()){
return false;
}
while(!stack1.isEmpty()){
if(stack1.pop() != stack2.pop()){
return false;
}
}
return true;
}
}
- 双指针
准备两个指针sTail
和tTail
,分别指向字符串s
与t
的尾部。再使用两个变量sCount
和tCount
来分别记录这两个字符串中'#'
号的数量。
从后往前开始遍历
- 遇到’#‘号,’#'计数器加1,指针前移一位
- 当前字符不是’#‘号,但是后面有’#’,即’#'计数器不为0,直接跳过,指针前移一位
- 当前字符不是’#‘号,且’#'计数器为0,比较两个字符,不同则结束遍历,返回
false
;
若某一个字符串先被遍历完了,则返回false
,若两个字符串同时被遍历完了,返回true
class Solution {
public boolean backspaceCompare(String s, String t) {
int sTail = s.length() - 1, tTail = t.length() - 1;
int sCount = 0, tCount = 0;
while(sTail >= 0 || tTail >= 0){
//消除'#'号
while(sTail >= 0){
if(s.charAt(sTail) == '#'){
sTail--;
sCount++;
} else if(sCount != 0){
sTail--;
sCount--;
} else{
break;
}
}
//消除'#'号
while(tTail >= 0){
if(t.charAt(tTail) == '#'){
tTail--;
tCount++;
} else if(tCount > 0){
tTail--;
tCount--;
} else {
break;
}
}
//当前字符既不是'#'号,后面也没有'#'号影响
if(sTail >= 0 && tTail >= 0){
if(s.charAt(sTail) != t.charAt(tTail)){
return false;
}
} else {
//走到这里有三种情况
//1. sTail >= 0 && tTail < 0
//2. sTail < 0 && tTail >= 0
//3. sTail < 0 && tTail < 0
//显然前两种情况属于 一个字符串遍历完了 另一个没有遍历完的情况 这种情况应该返回false
//而第三种情况,属于两个字符串的第一个位置都为'#'的
if(sTail >= 0 || tTail >= 0){
return false;
}
}
tTail--;
sTail--;
}
return true;
}
}
977.有序数组的平方
问题:给你一个按 非递减顺序 排序的整数数组 nums
,返回 每个数字的平方 组成的新数组,要求也按 非递减顺序 排序。
示例:
输入:nums = [-4,-1,0,3,10]
输出:[0,1,9,16,100]
解释:平方后,数组变为 [16,1,0,9,100]
排序后,数组变为 [0,1,9,16,100]
输入:nums = [-7,-3,2,3,11]
输出:[4,9,9,49,121]
思路:
- 平方后排序
class Solution {
public int[] sortedSquares(int[] nums) {
for(int i = 0; i < nums.length; i++){
nums[i] *= nums[i];
}
Arrays.sort(nums);
return nums;
}
}
- 双指针
负数平方之后可能成为最大数。所以数组平方的最大值就在数组的两端,不是最左边就是最右边,不可能是中间。
双指针,一个指针l
指向数组起始位置,另一个指针r
指向数组末尾。并且定义一个和原数组一样长的新数组res
,从后往前插入平方后的元素
-
若
nums[l] * nums[l] > nums[r] * nums[r]
,则res[--index] = nums[l] * nums[l]
,l
右移一位 -
若
nums[l] * nums[l] <= nums[r] * nums[r]
,则res[--index] = nums[r] * nums[r]
,r
左移一位
class Solution {
public int[] sortedSquares(int[] nums) {
int l = 0, r = nums.length - 1;
int index = nums.length;
int[] res = new int[index];
while(l <= r){
if(nums[l] * nums[l] > nums[r] * nums[r]){
res[--index] = nums[l] * nums[l];
l++;
} else{
res[--index] = nums[r] * nums[r];
r--;
}
}
return res;
}
}
整理思路,记录博客,以便复习。若有误,望指正~