数组篇刷题模板总结五——数组去重
LeetCode316
题目描述
代码实现
class Solution {
public String removeDuplicateLetters(String s) {
// 声明计数器,因为是ASCII码,所以256够用
int[] count = new int[256];
// 声明单调栈
Stack<Character> stk = new Stack<>();
// 声明布尔值数组来记录栈中元素存在与否
boolean[] inStack = new boolean[256];
// 初始化计数器
for (char i : s.toCharArray()) {
count[i]++;
}
for (char c : s.toCharArray()) {
count[c]--;
if (inStack[c]) {
// 注意:不是break;
continue;
}
while (!stk.isEmpty() && stk.peek() > c) {
// 如果去除此时的栈顶元素,该元素计数器将清零,则退出本次循环
if (count[stk.peek()] == 0) {
break;
}
// 之后还有栈顶元素,所以可以删除并且改变其在inStack中的状态
inStack[stk.pop()] = false;
}
// 压入当前缓冲区元素并改变其在inStack中的状态
stk.push(c);
inStack[c] = true;
}
// 打印结果
StringBuilder sb = new StringBuilder();
while (!stk.isEmpty()) {
sb.append(stk.pop());
}
// 反转,因为打印出来是反的
return sb.reverse().toString();
}
}
LeetCode26
题目描述
解题思路
本题声明必须采用原地修改的方式进行操作,所以不能申请额外的空间构造新数组来存储未重复元素最终返回结果。故采用双指针遍历数组并实时更新数组元素。只要快指针不属于已经更新好的慢指针中的元素,就添加进去。直至数组末尾,此时慢指针加一即索引加一就是新数组的长度。返回即可。
代码实现
class Solution {
public int removeDuplicates(int[] nums) {
// 使用快慢指针完成原地检索数组和修改操作
int fast = 0;
int slow = 0;
while (fast < nums.length) {
if (nums[fast] != nums[slow]) {
slow++;
nums[slow] = nums[fast];
}
fast++;
}
return slow + 1;
}
}
LeetCode83
题目描述
代码实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode deleteDuplicates(ListNode head) {
if (head == null) {
return null;
}
ListNode fast = head;
ListNode slow = head;
while (fast != null) {
if (fast.val != slow.val) {
slow = slow.next;
slow.val = fast.val;
}
fast = fast.next;
}
// 断开与后面重复元素的连接
slow.next = null;
return head;
}
}
LeetCode27
题目描述
代码实现
class Solution {
public int removeElement(int[] nums, int val) {
int slow = 0;
int fast = 0;
while (fast < nums.length) {
if (val != nums[fast]) {
nums[slow++] = nums[fast];
}
fast++;
}
return slow;
}
}
注意
本题与上面有一点不同是先给慢指针赋值,然后再递增慢指针。而上面去重是先增加慢指针再赋值。这是因为为了保证0-slow都没有等于val的元素,保证题意。
LeetCode283
题目描述
代码实现
class Solution {
public void moveZeroes(int[] nums) {
int slow = 0;
int fast = 0;
// 去掉为零的元素
while (fast < nums.length) {
if (nums[fast] != 0) {
nums[slow++] = nums[fast];
}
fast++;
}
// 在新数组末尾添加零
for (int p = slow; p < nums.length; p++) {
nums[p] = 0;
}
}
}