读书笔记之《程序员代码面试指南(链表问题)》 打印两个有序链表的公共部分 判断一个链表是否为回文结构 反转单向

链表是一种常见的重要的数据结构。它是动态地进行存储分配的一种结构。它可以根据需要开辟内存单元。链表有一个“头指针”变量,以head表示,它存放一个地址。该地址指向一个元素。链表中每一个元素称为“结点”,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。因此,head指向第一个元素:第一个元素又指向第二个元素;……,直到最后一个元素,该元素不再指向其它元素,它称为“表尾”,它的地址部分放一个“NULL”(表示“空地址”),链表到此结束。

package LinkedList;

/**
 * Created by zdmein on 2017/8/31.
 *
 * 打印两个有序链表的公共部分
 * 给定两个有序列表的头指针head1和head2,打印两个链表的公共部分。
 */
public class printCommonPart1 {
    public static class Node{
        public int value;
        public Node next;
        public Node(int data){
            this.value=data;
        }
    }

    public static void main(String args[]){
        Node head1=new Node(2);
        Node head11=new Node(3);
        Node head12=new Node(4);
        Node head13=new Node(7);
        head1.next=head11;
        head11.next=head12;
        head12.next=head13;

        Node head2=new Node(1);
        Node head21=new Node(3);
        Node head22=new Node(4);
        Node head23=new Node(9);
        head2.next=head21;
        head21.next=head22;
        head22.next=head23;

        printCommonPart(head1,head2);
    }

    public static void printCommonPart(Node head1,Node head2){
        System.out.println("Print Common Part: ");
        while(head1!=null&&head2!=null){
            if(head1.value==head2.value){
                System.out.println(head1.value);
                head1=head1.next;
                head2=head2.next;
            }else if(head1.value>head2.value){
                head2=head2.next;
            }else {
                head1=head1.next;
            }
        }
    }
}

判断一个链表是否为回文结构

题目:判断一个链表是否为回文结构。
要求:时间复杂度为 O(n),空间时间复杂度为O(1)。

思路分析:回文链表的特点就是对称,那么要判断是否回文,就可以用两个指针指向对称的节点,看它们的数据是否一样。由于是单向链表,不能同时用两个指针,从头尾向内部遍历取值比较。且本题对空间复杂度也有要求,所以可用如下方法实现。
具体步骤如下:
(1)先得到链表的中间节点;
(2)从中间节点的下一个节点开始,反转链表。
(3)从中间节点处,断开原链表。
(4)用两个指针分别向两个端点移动,同时进行比较,数据相同则继续,数据不同则直接返回false。直到遍历完成,最后返回true。

class ListNode {
        public char data;
        public ListNode next;
        public ListNode(char c){
            this.data=c;
        }
    }
    
    public static boolean isPalindrome(ListNode head ){
        ListNode slow = head;
        ListNode fast= head;
        
        if(fast==null || fast.next==null){
            return true;
        }
        //一个每次走2步,一个每次走1步,所以当fast到表尾,slow肯定把链表折半
        while(fast.next!=null&&fast.next.next!=null){
            fast=fast.next.next;
            slow=slow.next;
        }
        
        ListNode midNode=slow;
        ListNode firNode = slow.next; //后半段第一个节点
        ListNode cur=firNode.next; //从第一个节点开始插入
        firNode.next=null; //第一个节点最后变成最后一个节点,所以要置空
        while(cur!=null){
            ListNode nextNode = cur.next;
            cur.next=midNode.next;
            midNode=cur;
            cur=nextNode;
        }
        
        slow=head;
        fast=midNode.next;
        while (fast!=null){
            if(fast.data!=slow.data){
                return false;
            }
            slow=slow.next;
            fast=firNode.next;
        }
        return true;
    }

反转单向

反转单向链表

1-->2-->null

反转后

2-->1-->null

/**
 * Definition for ListNode.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int val) {
 *         this.val = val;
 *         this.next = null;
 *     }
 * }
 */

public class Solution {
    /*
     * @param head: n
     * @return: The new head of reversed linked list.
     */
    public ListNode reverse(ListNode head) {
        // write your code here
        
     ListNode pre=null;
            ListNode next1=null;
            while(head!=null){
                next1=head.next;
                head.next=pre;
                pre=head;
                head=next1;
            }
            return pre;
    }
}