该帖主要对链表的常见算法题进行总结,也是方便查看,具体的题目要求和思路可以点开链接查看,欢迎大家指点。
1 反转链表
输入一个链表,反转链表后,输出新链表的表头。
public ListNode ReverseList(ListNode head) {
ListNode reverse = null;
ListNode curr = head;
ListNode pre = null;
while(curr!=null){
ListNode next = curr.next;
if(next==null){
reverse = curr;
}
curr.next=pre;
pre = curr;
curr = next;
}
return reverse;
}
2 链表中第k个结点
输入一个链表,输出该链表中倒数第k个结点。
public ListNode FindKthToTail(ListNode head,int k) {
ListNode p1 = head;//快指针
ListNode p2 = head;//慢指针
if(head==null || k<=0){ //链表为空或k结点不再链表中
return null;
}
for(int i=0;i<k-1;i++){
if(p1.next!=null){
p1 = p1.next;
}
else{
return null;
}
}
while(p1.next!=null){
p1 =p1.next;
p2 = p2.next;
}
return p2;
}
3 从尾到头打印链表
输入一个链表,按链表值从尾到头的顺序返回一个ArrayList。
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack=new Stack<Integer>();
ArrayList<Integer> arr =new ArrayList<Integer>();
//把链表中的数推入栈
while(listNode!=null){
stack.push(listNode.val);
listNode =listNode.next;
}
while(!stack.isEmpty()){
arr.add(stack.pop());
}
return arr;
}
4 合并两个排序的链表
输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则。
public ListNode Merge(ListNode list1,ListNode list2) {
if(list1 == null){
return list2;
}
else if(list2 == null){
return list1;
}
else if(list1 ==null && list2 == null){
return null;
}
ListNode res =null;
if(list1.val<=list2.val){
res=list1;
res.next = Merge(list1.next,list2);
}else if(list1.val>list2.val){
res=list2;
res.next = Merge(list1,list2.next);
}
return res;
}
5 二叉搜索树与双向链表
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
public class Solution {
TreeNode Head = null;
public TreeNode Convert(TreeNode pRootOfTree) {
if(pRootOfTree == null)
return pRootOfTree;
TreeNode curr = pRootOfTree;
TreeNode pre = null;
Stack<TreeNode> stack = new Stack<>();
while(curr != null || !stack.isEmpty()){
if(curr != null){
stack.push(curr);
curr = curr.left;
}else{
curr = stack.pop();
if(Head == null){
Head = curr;
pre = Head;
}//说明是第一个
else{
pre.right = curr;
curr.left = pre;
pre = curr;
}
curr = curr.right;
}
}
return Head;
}}
6 删除链表中的重复结点
在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5
public ListNode deleteDuplication(ListNode pHead){
if (pHead==null || pHead.next==null){
return pHead;
}
ListNode gard = new ListNode(-1);
gard.next = pHead;
ListNode pre = gard;
ListNode curr = pHead;
while(curr!=null && curr.next!=null){
if(curr.val == curr.next.val){
int value = curr.val;
while(curr.next!=null && curr.next.val == value){
curr = curr.next;
}
curr = curr.next;
pre.next = curr;
}
else{
pre = pre.next;
curr = curr.next;
}
}
return gard.next;
}
7 链表中环的入口结点
给一个链表,若其中包含环,请找出该链表的环的入口结点,否则,输出null。
public ListNode EntryNodeOfLoop(ListNode pHead){
ListNode p1 =pHead;
ListNode p2 = pHead;
while(p1!=null && p2!=null){
p1 = p1.next;
if(p2.next == null){
return null;//p2.next ==null 时, 其next报错
}
p2 = p2.next.next;
if(p1 == p2){//有环
p2 = pHead;
while(p1 != p2){
p1 = p1.next;
p2 = p2.next;
}
return p1;
}
}
return null;
}