啊啊链表的题真的写时一时爽,调试火葬场,这个博客做了好久,磨磨蹭蹭拖了两天哎。
1.删除链表中的重复元素
leetcode82:Remove Duplicates fromSorted List II
题目在这里:
解题思路:
我一开始思路错了后面看了bobo老师的代码才明白怎么做。这里要找到重复的一段链表段,把整段链表段删除。这种题不太熟练,接下来还需要继续练。
代码:(因为要调试加上了main函数和create,print函数)
public class ListNode {
int val;
ListNode next;
ListNode(int x) { val = x; }
}
public ListNode createList(int[] array)
{
ListNode head=new ListNode(0);
ListNode tail=head;
for(int i=0;i<array.length;i++)
{
ListNode node=new ListNode(array[i]);
tail.next=node;
tail=node;
}
tail.next=null;
return head.next;
}
public void print(ListNode head) {
ListNode node=head;
while (node != null) {
System.out.print(node.val);
node=node.next;
}
}
public ListNode deleteDuplicates(ListNode pHead) {
ListNode dummyhead=new ListNode(0);
dummyhead.next=pHead;
ListNode pre=dummyhead;
ListNode cur=pre.next;
while(cur!=null)
{
int sum=0;
ListNode p=cur;
while(p!=null&&p.val==cur.val)
{
sum++;
p=p.next;
}
if(sum>1)
{
pre.next=p;
}else{
pre=cur;
}
cur=p;
}
return dummyhead.next;
}
public static void main(String args[])
{
int[] arr={1,1,1,2,5,6};
Solution so=new Solution();
so.print( so.createList(arr));
so.print(so.deleteDuplicates(so.createList(arr)));
}
}
2.反转链表
题目:输入一个链表,反转链表后,输出新链表的表头。
思路:一开始普通的思路就是用栈呗哈哈哈,然后优化用指针,啊不java没有指针。。实现了另外一种思路,思路图解如下:
用栈实现的代码:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
import java.util.Stack;
public class Solution {
public ListNode ReverseList(ListNode head) {
Stack<ListNode> s = new Stack<ListNode>();
ListNode tempnode;
ListNode newhead=new ListNode(0);
ListNode newtail=newhead;
tempnode=head;
if(head==null)
{
return null;
}else{
while(tempnode!=null)
{
s.push(tempnode);
tempnode=tempnode.next;
}
while(!s.empty())
{
ListNode node=s.pop();
newtail.next=node;
newtail=node;
}
newtail.next=null;
return newhead.next;
}
}
}
用图解思路实现的代码:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if(head==null)
{
return null;
}
ListNode pre=null;
ListNode cur=head;
while(cur!=null)
{
ListNode nextnode=cur.next;
cur.next=pre;
pre=cur;
cur=nextnode;
}
return pre;
}
}
还有用递归实现的代码。。。这里等我复习到递归再写吧。
3.链表中倒数第k个节点:
思路:
这道题的思路就是用两个指针p1 p2 ,使p1 p2保持k-1的距离,当p2到达最后一个NULL指针的时候,p1就是倒数第个结点了。
注意代码的鲁棒性,我第一次写的时候忽略了k=0的情况。
代码记录如下:
public ListNode FindKthToTail(ListNode head,int k) {
if(head==null||k==0)
{
return null;
}
ListNode p1=head;
ListNode p2=head;
for(int i=0;i<k;i++)
{
if(p1==null)
{
return null;
}
p1=p1.next;
}
while(p1!=null)
{
p1=p1.next;
p2=p2.next;
}
return p2;
}
4.合并两个排序的链表
思路:
我的思路首先是想用归并排序里面合并的思想做的,代码如下:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if(pHead==null)
{
return null;
}
ListNode head=new ListNode(0);
head.next=pHead;
ListNode p=head;
while(p.next!=null&&p.next.next!=null)
{
ListNode node1=p.next;
ListNode node2=node1.next;
if(node1.val==node2.val)
{
p.next=node2.next;
}
p=p.next;
}
return pHead;
}
public ListNode FindKthToTail(ListNode head,int k) {
if(head==null||k==0)
{
return null;
}
ListNode p1=head;
ListNode p2=head;
for(int i=0;i<k;i++)
{
if(p1==null)
{
return null;
}
p1=p1.next;
}
while(p1!=null)
{
p1=p1.next;
p2=p2.next;
}
return p2;
}
public ListNode Merge(ListNode list1,ListNode list2) {
ListNode p1=list1;
ListNode p2=list2;
ListNode head=new ListNode(0);
ListNode tail=head;
while(p1!=null&&p2!=null)
{
if(p1.val<p2.val)
{
tail.next=p1;
tail=p1;;
p1=p1.next;
}else{
tail.next=p2;
tail=p2;
p2=p2.next;
}
}
if(p1!=null)
{
while(p1!=null)
{
tail.next=p1;
tail=p1;
p1=p1.next;
}
}
if(p2!=null)
{
while(p2!=null)
{
tail.next=p2;
tail=p2;
p2=p2.next;
}
}
tail.next=null;
return head.next;
}
}
上面这段代码有个问题,就是没有考虑输入的鲁棒性(两个链表的一个或两个头节点为null)问题,所以必须要在前面加上这个。
if(list1==null)
{
return list2;
}
if(list2==null)
{
return list1;
}
剑指offer里面用了递归的写法,我觉得这样做太妙了,也是同样的思路:
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1==null)
{
return list2;
}
if(list2==null)
{
return list1;
}
ListNode node;
if(list1.val<list2.val)
{
node=list1;
node.next=Merge(list1.next,list2);
}
else{
node=list2;
node.next=Merge(list1,list2.next);
}
return node;
}
}
5.Leetcode 237
Delete Node in a Linked List
题解:
这道题通过改变值的变化来达到删除结点的效果。当然,记录下要删除结点的前一个结点也是可以的。
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public void deleteNode(ListNode node) {
if(node==null||node.next==null)
{
System.out.println("error");
}
node.val=node.next.val;
node.next=node.next.next;
}
}