<1>链表
1----从尾到头打印链表
输入一个链表,从尾到头打印链表每个节点的值。
import java.util.ArrayList;
import java.util.Stack;
public class Solution {
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
ArrayList<Integer> result = new ArrayList<Integer>();
Stack<Integer> stack = new Stack<Integer>();
while(listNode!=null){
stack.push(listNode.val);
listNode = listNode.next;
}
while(!stack.isEmpty()){
result.add(stack.pop());
}
return result;
}
}
2--合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
主要思路
1、首先处理空链表,当其中一个为空链表时,直接输出另一个;当两个均为空链表时,输出null
2、比较 list1 和 list2 的头结点,较小的头结点作为合并后新链表的头结点
3、确定新链表的头结点之后,就可以递归比较余下的结点了
/*
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 head = null;
if(list1.val <= list2.val){
head = list1;
list1.next = Merge(list1.next,list2);
}
else{
head = list2;
list2.next = Merge(list1,list2.next);
}
return head;
}
}
非递归实现版
/*
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;
//创建一个 val 为0的结点
ListNode head = new ListNode(0);
ListNode root = head;
while (list1 != null && list2 != null) {
if (list1.val < list2.val) {
head.next = list1;
list1 = list1.next;
} else {
head.next = list2;
list2 = list2.next;
}
head = head.next;
}
if (list1 != null) {
head.next = list1;
}
if (list2 != null) {
head.next = list2;
}
return root.next;
}
}
3----删除链表中重复的结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的
输入链表:1->2->3->3->4->4->5
处理后为:1->2->5
非递归的代码:
1. 首先添加一个头节点,以方便碰到第一个,第二个节点就相同的情况
2.设置 pre ,last 指针, pre指针指向当前确定不重复的那个节点,而last指针相当于工作指针,一直往后面搜索。
public class Solution {
public ListNode deleteDuplication(ListNode pHead)
{
if( pHead == null || pHead.next == null)
return pHead;
ListNode head = new ListNode(-1);
head.next = pHead;
ListNode pre = head;
ListNode cur = head;
while( cur!=null){
while(cur.next!=null && cur.val == cur.next.val){
cur = cur.next;
}
if(pre.next == cur) // 开始节点情况
pre = pre.next;
else
pre.next = cur.next;
cur = cur.next;
}
return head.next;
}
}
4----反转链表
输入一个链表,反转链表后,输出链表的所有元素。
要想反转链表,对于结点i,我们要把它的next指向它的前趋,因此我们需要保存前趋结点,同时,如果我们已经把i的next重新赋值,会无法找到i的后继,因此,在重新赋值之前,我们要保存i的后继。
//将原来的链表断链,将current的下一个结点指向新链表的头结点
public class Solution {
public ListNode ReverseList(ListNode head) {
ListNode ReverseHead = null ;//反转之后的头指针
ListNode Node = head;//当前指针
ListNode PreNode = null;//当前指针的前一指针
//处理链表为空以及只有一个结点的情况
if(head == null || head.next == null)
return head;
while(Node != null) {
ListNode nextNode = Node.next;//保存当前结点的下一结点,防止链表截断
if(nextNode == null)
ReverseHead = Node;
Node.next = PreNode ; //将原来的链表断链,将current的下一个结点指向新链表的头结点//将当前链表的next指向前一结点
//后移Node、NextNode,将后面的结点也反转
PreNode = Node;
Node = nextNode ;
}
return ReverseHead;
}
}
5----链表中倒数第k个结点
输入一个链表,输出该链表中倒数第k个结点。
定义两个指针,第一指针先走k-1步,第二个指针不动,当从第k步起,两个指针一起动(两个指针的距离始终是k-1)。当第一个指针走到为节点时,第二个指针恰好是倒数第k个节点。
public class Solution {
public ListNode FindKthToTail(ListNode head,int k) {
ListNode fast = head;
ListNode slow = head;
if(k<=0)
return null;
// fast 向前走k步
while(k>=1){
if(fast == null){
return null;
}
fast = fast.next;
k--;
}
// 空的时候说明是第一个结点
if(fast == null ){
return slow;
}
// 一起走
while(fast.next!=null){
fast = fast.next;
slow = slow.next;
}
return slow.next;
}
}