设计核心:
用一个数来计数,表示当前的元素出现了多少次
public static ListNode deleteDuplicates(ListNode head) {
if(head == null || head.next == null) return head;
ListNode newHead = new ListNode();
ListNode newBody = newHead;
ListNode pre = head;
ListNode tail = pre.next;
int count = 1;
while (tail != null) {
if(pre.val == tail.val) {
count++;
} else {
if(count == 1) {
newBody.next = new ListNode(pre.val);
newBody = newBody.next;
}
pre = tail;
count = 1;
}
if(tail.next == null && count == 1) {
newBody.next =new ListNode(pre.val);;
break;
}
tail = tail.next;
}
return newHead.next;
}
简单的链表题
读题可知
小于target的数都放在前
大于等于target的数都放在后
且都按照顺序
则可创建两个链表分寸存储再拼接即可
public ListNode partition(ListNode head, int x) {
ListNode part_1 = new ListNode();//前部分
ListNode part_1_p = part_1;//前部分指针
ListNode part_2 = new ListNode();//后部分
ListNode part_2_p = part_2;//后部分指针
while (head != null) {
if(head.val < x) {
part_1_p.next = new ListNode(head.val);
part_1_p = part_1_p.next;
}else {
part_2_p.next = new ListNode(head.val);
part_2_p = part_2_p.next;
}
head = head.next;
}
part_1_p.next = part_2.next;
return part_1.next;
}
实现思路 :以1->2->3->4->5, m = 2, n=4 为例:
定位到要反转部分的头节点 2,head = 2;前驱结点 1,pre = 1;
当前节点的下一个节点3调整为前驱节点的下一个节点 1->3->2->4->5,
当前结点仍为2, 前驱结点依然是1,重复上一步操作。。。
1->4->3->2->5.
完整代码:
public ListNode reverseBetween(ListNode head, int left, int right) {
if(left == right) return head;
ListNode dummy = new ListNode(0);
dummy.next = head;
ListNode pre = dummy;
for(int i = 1; i < left; i++){
pre = pre.next;
}
head = pre.next;
for(int i = left; i < right; i++){
ListNode nex = head.next;
head.next = nex.next;
nex.next = pre.next;
pre.next = nex;
}
return dummy.next;
}