(1)从尾到头打印链表
题目描述
输入一个链表,从尾到头打印链表每个节点的值。
思想:用栈来存储节点,顺序出栈就为从尾到头打印节点值
public static void main(String[] arg) {
ListNode a=new ListNode(0);
a.next=new ListNode(1);
a.next.next=new ListNode(2);
a.next.next.next=new ListNode(3);
a.next.next.next.next=new ListNode(4);
a.next.next.next.next.next=new ListNode(5);
System.out.println("从后向前打印链表的节点");
printListFromTailToHead(a);
}
private static void printListFromTailToHead(ListNode a) {
if(a==null) {
return ;
}
Stack<ListNode> stack=new Stack<ListNode>();
while(a!=null) {
stack.push(a);
a=a.next;
}
while(!stack.isEmpty()) {
System.out.print(stack.pop().val+" ");
}
}
(2)链表中倒数第k个结点
题目描述
输入一个链表,输出该链表中倒数第k个结点。
思路:先计数链表的节点,倒数第k个节点,即为正数n-k个节点
public static void main(String[] arg) {
ListNode a=new ListNode(0);
a.next=new ListNode(1);
a.next.next=new ListNode(2);
a.next.next.next=new ListNode(3);
a.next.next.next.next=new ListNode(4);
a.next.next.next.next.next=new ListNode(5);
System.out.println("链表中倒数第k个结点");
FindKthToTail(a,5);
}
private static void FindKthToTail(ListNode a, int k) {
if(a==null) {
return ;
}
int count=0;
ListNode ln=a;
while(ln!=null) {
count++;
ln=ln.next;
}
ListNode lo=a;
for(int i=0;i<count;i++) {
if(i==k-1) {
System.out.println(lo.val+"此时,k的值为"+k);
}
lo=lo.next;
}
}
(3)反转链表
题目描述
输入一个链表,反转链表后,输出链表的所有元素。
思路:链表操作
public static void main(String[] arg) {
ListNode a=new ListNode(0);
a.next=new ListNode(1);
a.next.next=new ListNode(2);
a.next.next.next=new ListNode(3);
a.next.next.next.next=new ListNode(4);
a.next.next.next.next.next=new ListNode(5);
System.out.println("反转链表:");
ReverseList(a);
}
private static void ReverseList(ListNode pHead) {
if(pHead==null) {
return ;
}
ListNode pre=null;
ListNode next=null;
while(pHead!=null) {
next=pHead.next;//用next来保存pHead的下一个节点
pHead.next=pre;//pHead.next指向pre实现反转
pre=pHead;//依次移动到下一节点
pHead=next;
}
while(pre!=null) {
System.out.print(pre.val+" ");
pre=pre.next;
}
}
(3)合并两个排序的链表
题目描述
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
public static void main(String[] arg) {
ListNode a=new ListNode(1);
a.next=new ListNode(3);
a.next.next=new ListNode(5);
a.next.next.next=new ListNode(7);
a.next.next.next.next=new ListNode(9);
a.next.next.next.next.next=new ListNode(11);
ListNode b=new ListNode(0);
b.next=new ListNode(2);
b.next.next=new ListNode(4);
b.next.next.next=new ListNode(6);
b.next.next.next.next=new ListNode(8);
b.next.next.next.next.next=new ListNode(10);
System.out.println("合并链表");
Merge(a,b);
}
private static void Merge(ListNode a, ListNode b) {
if(a==null&&b==null) {
return ;
}
if(a!=null&&b==null) {
return ;//这里自己写,我暂时返回空
}
if(a==null&&b!=null) {
return ;//这里自己写,我暂时返回空
}
if(a!=null&&b!=null) {
ListNode p=new ListNode(-1);
ListNode ln=p;
while(a!=null&&b!=null) {
if(a.val<b.val) {
ln.next=a;
a=a.next;
}else {
ln.next=b;
b=b.next;
}
ln=ln.next;
}
if(a!=null) {
ln.next=a;
}
if(b!=null) {
ln.next=b;
}
while(p.next!=null) {
System.out.print(p.next.val+" ");
p.next=p.next.next;
}
}
}
(4)复杂链表的复制
题目描述
输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head。(注意,输出结果中请不要返回参数中的节点引用,否则判题程序会直接返回空)
public RandomListNode Clone(RandomListNode pHead)
{
if(pHead==null){
return null;
}
RandomListNode p=pHead;
RandomListNode t=pHead;
while(p!=null){//复制节点
RandomListNode q=new RandomListNode(p.label);
q.next=p.next;
p.next=q;
p=q.next;
}
while(t!=null){
RandomListNode q=t.next;
if(t.random!=null){
q.random=t.random.next;
}
t=q.next;
}
RandomListNode s=new RandomListNode(0);
RandomListNode s1=s;
while(pHead!=null){
RandomListNode q=pHead.next;
s.next=q;
pHead.next=q.next;//原来的指向断开,目的使得pHead可以顺利指向源列表的下一节点
s=s.next;
pHead=pHead.next;
}
return s1.next;
}
(5)两个链表的第一个公共结点
题目描述
输入两个链表,找出它们的第一个公共结点。
public static void main(String[] arg) {
ListNode a=new ListNode(1);
a.next=new ListNode(3);
a.next.next=new ListNode(5);
a.next.next.next=new ListNode(7);
a.next.next.next.next=new ListNode(9);
a.next.next.next.next.next=new ListNode(11);
ListNode b=new ListNode(5);
b.next=new ListNode(2);
b.next.next=new ListNode(4);
b.next.next.next=new ListNode(6);
b.next.next.next.next=new ListNode(8);
b.next.next.next.next.next=new ListNode(10);
System.out.println("两个链表的第一个公共结点:");
FindFirstCommonNode(a,b);
}
private static void FindFirstCommonNode(ListNode a, ListNode b) {
if(a==null||b==null) {
return ;
}
ArrayList<Integer> list=new ArrayList<Integer>();
while(a!=null) {
list.add(a.val);
a=a.next;
}
while(b!=null) {
if(list.contains(b.val)) {
System.out.print(b.val);
return ;
}
b=b.next;
}
}
(6)链表中环的入口结点
题目描述
一个链表中包含环,请找出该链表的环的入口结点。
思路:定义两个节点,同时遍历一个比一个快一倍,当它们相遇的时候差距为一环的数量,然后将一个置为起点,两个同时走,相遇的地点即为环的入口。
public static void main(String[] arg) {
ListNode a=new ListNode(0);
a.next=new ListNode(1);
a.next.next=new ListNode(2);
a.next.next.next=new ListNode(3);
a.next.next.next.next=new ListNode(4);
a.next.next.next.next.next=a.next.next;
System.out.println("链表中环的入口结点为:");
EntryNodeOfLoop(a);
}
private static void EntryNodeOfLoop(ListNode a) {
if(a==null) {
return ;
}
ListNode p=a;
ListNode q=a;
while(q!=null&&q.next!=null) {
p=p.next;
q=q.next.next;
if(p.val==q.val) {
q=a;
while(p.val!=q.val) {
p=p.next;
q=q.next;
}
System.out.print(p.val);
return ;
}
}
}
(7)删除链表中重复的结点
题目描述
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
public static void main(String[] arg) {
ListNode a=new ListNode(0);
a.next=new ListNode(1);
a.next.next=new ListNode(2);
a.next.next.next=new ListNode(3);
a.next.next.next.next=new ListNode(4);
a.next.next.next.next.next=new ListNode(4);
System.out.println("链表中环的入口结点为:");
deleteDuplication(a);
}
private static void deleteDuplication(ListNode a) {
if(a==null) {
return ;
}
ListNode first=new ListNode(0);
first.next=a;
ListNode pre=a;
ListNode last=first;
while(pre!=null) {
if(pre.val==pre.next.val) {
int ps=pre.val;
while(pre!=null&&ps==pre.val) {
pre=pre.next;
}
last.next=pre;
}else {
last=pre;
pre=pre.next;
}
}
while(first.next!=null) {
System.out.print(first.next.val+" ");
first.next=first.next.next;
}
}