【Java数据结构】链表面试题
- 一、移除链表元素
- 二、反转链表
- 三、链表的中间结点
- 四、删除链表的倒数第 N 个结点
- 五、合并两个有序链表
- 六、链表分割
- 七、链表的回文结构
- 八、相交链表
- 九、环形链表
此篇博客希望对你有所帮助(帮助你更加了解链表),不懂的或有错误的也可在评论区留言,错误必改评论必回!!!持续关注,下一篇博客是java数集合框架中的队列和栈!!!
一、移除链表元素
给你一个链表的头节点 head 和一个整数 val ,请你删除链表中所有满足 Node.val == val 的节点,并返回 新的头节点 。
移除链表元素
public ListNode removeElements( int val) {
if(head==null){
return null;
}
ListNode prev=head;
ListNode cur=head.next;
while(cur!=null){
if(cur.val==val){
prev.next =cur.next;
cur=cur.next;
}else{
prev=cur;
cur=cur.next;
}
}
if (head.val == val) {
head=head.next;
}
return head;
}
二、反转链表
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
反转链表
public ListNode reverseList(ListNode head) {
if (head == null) {
return head;
}
ListNode cur = head.next;
head.next = null;
while (cur != null) {
ListNode curN = cur.next;
cur.next = head;
head = cur;
cur = curN;
}
return head;
}
三、链表的中间结点
给你单链表的头结点 head ,请你找出并返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。
链表的中间结点
public ListNode middleNode(ListNode head) {
if (head == null) {
return head;
}
ListNode slow = head;
ListNode fast = head;
while (fast != null) {
if (fast.next == null) {
break;
} else {
fast = fast.next.next;
}
slow = slow.next;
}
return slow;
}
四、删除链表的倒数第 N 个结点
给定一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。
删除链表的倒数第 N 个结点
public ListNode removeNthFromEnd(int n) {
if (head == null) {
return null;
}
ListNode cur = head;
if (n == 1) {
head = head.next;
}
int count=0;
ListNode tmp=head;
while(tmp!=null){
count++;
tmp=tmp.next;
}
for (int i = 0; i < count- n+1; i++) {
cur = cur.next;
}
ListNode curN = cur.next;
if (curN.next == null) {
cur.next = null;
} else {
cur.next = curN;
}
return head;
}
五、合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
合并两个有序链表
public ListNode mergeTwoLists(ListNode list1, ListNode list2) {
ListNode head=new ListNode();
ListNode tmp=head;
while(list1!=null&&list2!=null){
if(list1.val<list2.val){
tmp.next=list1;
list1=list1.next;
tmp=tmp.next;
}else{
tmp.next=list2;
list2=list2.next;
tmp=tmp.next;
}
}
if(list1==null){
tmp.next=list2;
}
if(list2==null){
tmp.next=list1;
}
return head.next;
}
六、链表分割
现有一链表的头指针 ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。
链表分割
public ListNode partition(ListNode pHead, int x) {
ListNode ap = null;
ListNode an = null;
ListNode bp = null;
ListNode bn = null;
ListNode cur = pHead;
while (cur != null) {
if (cur.val < x) {
if (ap == null) {
ap = an = cur;
} else {
an.next = cur;
an = an.next;
}
} else {
if (bp == null) {
bp = bn = cur;
} else {
bn.next = cur;
bn = bn.next;
}
}
cur = cur.next;
}
if (ap == null) {
return bp;
}
an.next = bp;
if (bn != null) {
bn.next = null;
}
return ap;
}
七、链表的回文结构
对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。
给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。
链表的回文结构
public boolean chkPalindrome(ListNode head) {
if(head==null){
return true;
}
ListNode slow=head;
ListNode fast=head;
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
}
ListNode cur=slow.next;
while(cur!=null){
ListNode curN=cur.next;
cur.next=slow;
slow=cur;
cur=curN;
}
while(head!=slow){
if(head.val!=slow.val){
return false;
}
if(head.next==slow){
return true;
}
head= head.next;
slow=slow.next;
}
return true;
}
八、相交链表
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点,返回 null 。
相交链表
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
int lenA=1;
int lenB=1; ListNode tempA = headA, tempB = headB;
while (headA.next != null) {
headA = headA.next;
lenA++;
}
while (headB.next != null) {
headB = headB.next;
lenB++;
}
headA = tempA;
headB = tempB;
if (lenA > lenB) {
for (int i = lenB; i < lenA; i++) {
headA = headA.next;
}
}
if (lenB > lenA) {
for (int i = lenA; i < lenB; i++) {
headB = headB.next;
}
}
if (headA == headB) return headA;
while (headA.next != null) {
headA = headA.next;
headB = headB.next;
if (headA == headB) return headA;
}
return null;
}
九、环形链表
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
环形链表
public boolean hasCycle(ListNode head) {
ListNode fast=head;
ListNode slow=head;
if(head==null){
return false;
}
while(fast!=null&&fast.next!=null){
fast=fast.next.next;
slow=slow.next;
if(fast==slow){
return true;
}
}
return false;
}