203.移除链表元素
需要考虑好滑动窗口的起始和终止条件
class Solution {
public ListNode removeElements(ListNode head, int val) {
ListNode dummyNode = new ListNode(-1,head);
ListNode temp = dummyNode;
while(temp.next!=null){
if(temp.next.val==val){
temp.next=temp.next.next;
}else{
temp=temp.next;
}
}
return dummyNode.next;
}
}
707. 设计链表
对我来说相当困难的一题……设计链表时使用虚拟头结点可以节省很多判断。尤其要注意size的变化
单链表:
class MyLinkedList {
int size;
// 虚拟头结点
ListNode head;
class ListNode {
int val;
ListNode next;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
}
public MyLinkedList() {
this.size = 0;
this.head = new ListNode(-1);
}
public int get(int index) {
if(index<0 ||index>=size){
return -1;
}
ListNode cur = head;
for(int i=0;i<= index;i++){
cur= cur.next;
}
return cur.val;
}
public void addAtHead(int val) {
addAtIndex(0,val);
}
public void addAtTail(int val) {
addAtIndex(size,val);
}
public void addAtIndex(int index, int val) {
if(index<0){
index = 0;
}
if(index>size){
return;
}
ListNode pre = head;
for(int i = 0;i<index;i++){
pre = pre.next;
}
ListNode add = new ListNode(val);
add.next = pre.next;
pre.next = add;
size++;
}
public void deleteAtIndex(int index) {
if(index<0 ||index>=size){
return;
}
ListNode pre = head;
for(int i =0;i<index;i++){
pre= pre.next;
}
pre.next = pre.next.next;
size--;
}
}
双链表:
与单链表不同,双链表查找时可以双向查找,添加时是单项添加(双向太过复杂),要注意前后节点的指针都需要修改
class MyLinkedList {
int size;
// 虚拟头结点
ListNode head;
ListNode tail;
class ListNode {
int val;
ListNode next;
ListNode pre;
ListNode() {
}
ListNode(int val) {
this.val = val;
}
}
public MyLinkedList() {
this.size = 0;
this.head = new ListNode(-1);
this.tail = new ListNode(-1);
head.next = tail;
tail.pre = head;
}
public int get(int index) {
if(index<0 ||index>=size){
return -1;
}
//与单链表不同,需要判断哪端取比较快
ListNode cur = head;
if(size/2<index){
for(int i=0;i<= index;i++){
cur= cur.next;
}
}else{
cur = tail;
for(int i=0;i<size-index;i++){
cur= cur.pre;
}
}
return cur.val;
}
public void addAtHead(int val) {
addAtIndex(0,val);
}
public void addAtTail(int val) {
addAtIndex(size,val);
}
public void addAtIndex(int index, int val) {
if(index<0){
index = 0;
}
if(index>size){
return;
}
//找到前驱
ListNode pre = this.head;
for(int i=0; i<index; i++){
pre = pre.next;
}
//新建结点
ListNode newNode = new ListNode(val);
newNode.next = pre.next;
pre.next.pre = newNode;
newNode.pre = pre;
pre.next = newNode;
size++;
}
public void deleteAtIndex(int index) {
if(index<0 ||index>=size){
return;
}
ListNode pre = head;
for(int i =0;i<index;i++){
pre= pre.next;
}
pre.next.next.pre = pre;
pre.next = pre.next.next;
size--;
}
}
206.反转链表
反转链表时,最重要的是理解指针的移动,调转的是指针的方向
双指针:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode curr = head;
ListNode temp = null;
while(curr!=null){
temp = curr.next;
curr.next = pre;
pre = curr;
curr = temp;
}
return pre;
}
}
递归法:
class Solution {
public ListNode reverseList(ListNode head) {
return reverse(null,head);
}
ListNode reverse(ListNode l1,ListNode l2){
if(l2==null){
return l1;
}
ListNode temp = l2.next;
l2.next = l1;
l1 = l2;
l2 = temp;
return reverse(l1,l2);
}
}
1070

被折叠的 条评论
为什么被折叠?



