OJ面试题
1. 删除一个链表所有值为key的节点
public void removeAllKey(int key) {
Node pre = this.head;
Node cur =this.head.next;
while (cur!=null){
if (cur.data == key){
pre.next = cur.next;
cur = cur.next;
size--;
}else {
pre = cur;
cur = cur.next;
}
}
if(this.head.data==key){
head = head.next;
}
}
2. 反转一个单链表
public Node reverseList(){
Node reverseHead = null; //反转后新的头节点
Node cur = this.head; //cur代表当前需要反转的节点
Node prev = null; //cur的前驱信息
while (cur!= null){
Node curNext = cur.next;
if(curNext == null){
reverseHead = cur;
}
cur.next = prev;
prev = cur;
cur = curNext;
}
return reverseHead;
}
3. 找到单链表的中间节点
public Node middleNode(){
Node cur = this.head;
int len = getLength()/2;
for(int i = 0;i<len;i++){
cur = cur.next;
}
return cur;
}
4. 找到单链表的倒数第k个节点
public Node findKthToTail(int k){
if(this.head==null || k<=0 ){
return null;
}
Node fast = this.head;
Node slow = this.head;
for(int i = 0;i<k-1;i++){
if(fast.next!=null){
fast = fast.next;
}else{
System.out.println("没有这个节点");
return null;
}
}
while (fast.next!=null){
fast = fast.next;
slow = slow.next;
}
return slow;
}
5. 合并两个有序链表
public Node mergeTwoLists(Node headA,Node headB){
Node newHead = new Node(-1);//虚拟节点
Node tmpHead = newHead;
//谁小串谁
while (headA!=null && headB!=null){
if(headA.getData()>=headB.getData()){
tmpHead.next = headB;
tmpHead = tmpHead.next;
headB = headB.next;
}else {
tmpHead.next = headA;
tmpHead = tmpHead.next;
headA = headA.next;
}
}
if(headA!=null){
tmpHead.next = headA;
}
if(headB!=null){
tmpHead.next = headB;
}
return newHead.next;
}
6. 给定x为基准将链表分割成两部分,所有小于x的节点排在大于等于x的节点之前
public Node partition(int x){
Node beforeStart = null;
Node beforeEnd = null;
Node lastStart = null;
Node lastEnd = null;
Node cur = this.head;
while (cur!=null){
Node curNext = cur.next;
cur.next = null;
if(cur.data < x){ //前半部分
if(beforeStart==null){ //放第一个节点
beforeStart = cur;
beforeEnd = beforeStart;
} else {
beforeEnd.next = cur;
beforeEnd = cur;
}
}else { //后半部分
if(lastStart ==null){ //放第一个节点
lastStart = cur;
lastEnd = cur;
} else {
lastEnd.next = cur;
lastEnd = lastEnd.next;
}
}
cur = curNext;
}
if(beforeStart == null){ //如果没有比x小的
return lastStart;
}
beforeEnd.next = lastStart; // 拼接单链表
return beforeStart;
}
7. 删除有序链表中重复节点,不保留重复节点,返回头指针
public Node delectDuplication(){
Node node = new Node(-1);
Node cur = this.head;
Node tmpHead = node; //虚拟节点
while (cur!=null){
if(cur.next!=null && cur.data == cur.next.data){
while (cur.next!=null && cur.data == cur.next.data){
cur = cur.next;
}
cur = cur.next;
tmpHead.next = cur;
} else {
//确定不为重复节点
tmpHead.next = cur;
tmpHead = cur;
cur = cur.next;
}
}
return node.next;
}
8 . 链表的回文结构
public boolean chkPalindrme(){
Node fast = this.head;
Node slow = this.head;
while (fast!=null && fast.next!=null) {
fast = fast.next.next;
slow = slow.next;
}
//slow指向中间节点
Node p = slow.next;
Node pNext = p.next;
while (p!=null){ //链表后半部分逆置
p.next = slow;
slow = p;
p = p.next;
if(p!=null){
pNext = p.next;
}
}
//后半部分已经逆置
while (this.head != slow){
if(this.head.data!=slow.data){
return false;
}
if(this.head.next==slow){ //偶数个
return true;
}
head = head.next;
slow = slow.next;
}
return true;
}
9. 输入两个链表,找到相交节点
public Node getIntersectionNode( Node headA, Node headB){
Node pL = headA;
Node pS = headB;
int lenA = 0;
while (pL!=null){
lenA++;
pL = pL.getNext();
}
int lenB = 0;
while (pS!=null){
lenB++;
pS = pS.getNext();
}
pL = headA; //起初假设A链表长
pS = headB;
int len = lenA-lenB;
if(len<0){
pL = headB; //B单链表是长的
pS = headA;
len = lenB-lenA;
}
//最长的单链表是PL,并且差值是一个正数
for(int i = 0;i<len;i++){
pL = pL.getNext();
}
//PL和ps在同一起跑线上
while (pL!=pS && pL!=null&&pS!=null){
pL = pL.getNext();
pS = pS.getNext();
}
if(pL == pS && pL!=null && pS!=null){
return pL;
}
return null;
}
10 . 单链表是否有环
public boolean hasCycle(){
Node fast = this.head;
Node slow = this.head;
while (fast!=null && fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
return true;
}
}
return false;
}
11. 求链表入环的第一个结点,无环则返回null
public Node detectCycle(){
Node fast = this.head;
Node slow = this.head;
while (fast!=null && fast.next!=null){
fast = fast.next.next;
slow = slow.next;
if(fast == slow){
break;
}
}
if(fast==null||fast.next==null){
return null;
}
slow = this.head;
while (fast!=slow){
fast = fast.next;
slow = slow.next;
}
return slow;
}