数组题目的核心:遍历,进行判断是否有资格进行某个操作,即筛选并进行巧妙操作
26.删除有序数组中的重复项(LeetCode 26)
采用链表的双指针 i j
i 指针 是遍历指针,j 指针是标记指针
每次遍历看 遍历指针的数据与前一个的数据是否相同
相同 : i 继续往后遍历
不同 : 令标记位置的数 = i 现在的数值 ,标记位++,每次for循环i 会自己++
注意 : 边界情况 当刚开始遍历时,是没有前一位的数值与之相比,会报数组越界
判断 : 要加 i == 0 时直接与不同处理情况相同
int n = nums.length;
int j = 0;
for(int i = 0; i < n; i++){
if( i == 0 || nums[i] != nums[i - 1]){
nums[j] = nums[i];
j++;
}
}
return j;
203.移除链表元素
有两种方法:构造头节点方便处理一样 和 不构造新头节点
我比较喜欢不构造,就是处理头要不要删除多加一个判断而已
class Solution {
public ListNode removeElements(ListNode head, int val) {
if(head == null) return null;
if(head.val == val) return removeElements(head.next,val);
ListNode p = head.next , q = head ;
while(p != null){
if(p.val == val){
q.next = p.next;
p = p.next;
} else {
q = q.next;
p = p.next;
}
}
return head;
}
}
第一次 没通过的原因 是 全链表的数值 都是相同 且要删除的
所以,当头节点的数值 为要删除的,就要用递归处理,不能无脑头的下一个
这题 没限制 数字只能出现 一次
解题逻辑:
1.空判断
2.边界条件:当头节点为要删除的节点
3.循环:链表的删除问题
构造头节点方便处理一致的代码
class Solution {
public ListNode removeElements(ListNode head, int val) {
if (head == null) return null;
ListNode dummy = new ListNode(-1);
dummy.next = head;
ListNode pre = dummy;
ListNode cur = head;
while (cur != null) {
if (cur.val == val) {
pre.next = cur.next;
} else {
pre = cur;
}
cur = cur.next;
}
return dummy.next;
}
}
160.相交链表
代码逻辑:
如果有相交:则这两个指针在遍历完本链表完,到令一个链表时,肯定会在相交节点时,指向相同指针,因为如果有相交则两个链表的个数遍历的个数相同
如果不相交: 则会在两个链表的公倍数的时候 会指向链尾的 null
一开始看不懂 题解的原因: 就是没有图解的 清晰
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
if(headA == null || headB == null) return null;
ListNode pa = headA;
ListNode pb = headB;
while(pa != pb){
if(pa == null){
pa = headB;
} else {
pa = pa.next;
}
if(pb == null){
pb = headA;
} else {
pb = pb.next;
}
}
return pa;
}
}
283.(举一反三)移动零
LC26题目 + 剩下的填充为 0
判断条件,改成不等于0,不是不等于前一个数
class Solution {
public void moveZeroes(int[] nums) {
int j = 0;
for(int i = 0; i < nums.length ; i++){
if( nums[i] != 0){
nums[j] = nums[i];
j++;
}
}
for(;j < nums.length; j++){
nums[j] = 0;
}
}
}