zoukankan      html  css  js  c++  java
  • 面试题目——《CC150》链表

    面试题2.1:编写代码,移除未排序链表中的重复结点  进阶:如果不得使用临时缓冲区,该怎么解决?

    package cc150;
    
    import java.util.HashMap;
    import java.util.Map;
    
    
    public class DeleteDups {
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		LinkedListNode Node0 = new LinkedListNode(1);
    		LinkedListNode Node1 = new LinkedListNode(1);
    		LinkedListNode Node2 = new LinkedListNode(2);
    		LinkedListNode Node3 = new LinkedListNode(3);
    		Node0.next = Node1;
    		Node1.next = Node2;
    		Node2.next = Node3;
    		deleteDups(Node0);
    		LinkedListNode temp = Node0;
    		while(temp != null){
    			System.out.println(temp.iData);
    			temp = temp.next;
    		}
    	}
    	
    //	public static void deleteDups(LinkedListNode n){
    //		Map<Integer,Boolean> map = new HashMap<Integer,Boolean>();
    //		LinkedListNode pre = null;	//记录上一次不重复的结点
    //		while(n != null){
    //			if(map.containsKey(n.iData)){
    //				pre.next = n.next;
    //			}else{
    //				map.put(n.iData, true);
    //				pre = n;
    //			}
    //			n = n.next;
    //		}
    //		
    //	}
    	
    	public static void deleteDups(LinkedListNode head){
    		if(head == null)
    			return;
    		LinkedListNode current = head;	
    		while(current != null){
    			LinkedListNode runner = current;
    			while(runner.next != null){	//是runner.next
    				if(runner.next.iData == current.iData)	//判断内层所有结点是否等于外层结点
    					runner.next = runner.next.next;
    				else
    					runner = runner.next;
    			}
    			current = current.next;
    		}
    	}
    
    }
    

    面试题2.2:实现一个算法,找出单向链表中倒数第k个结点。——《剑指Offer》面试题15 (找出) &《Leetcode》removeNthNode (移除)

    package cc150;
    
    public class NthToLast {
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		ListNode Node1 = new ListNode(1);
    		ListNode Node2 = new ListNode(2);
    		ListNode Node3 = new ListNode(3);
    		Node1.next = Node2;
    		Node2.next = Node3;
    		System.out.println(nthToLast(Node1,1).val);
    	}
    	
    	public static ListNode nthToLast(ListNode head,int k){	//返回链表的倒数第k个结点
    		if(k <= 0)
    			return null;
    		ListNode p1 = head;
    		ListNode p2 = head;
    		
    		for(int i=0;i<k-1;i++){
    			if(p2 == null)
    				return null;
    			p2 = p2.next;
    		}
    		if(p2 == null)
    			return null;
    		
    		while(p2.next != null){
    			p1 = p1.next;
    			p2 = p2.next;
    		}
    		return p1;
    	}
    	
    	public static class ListNode {
    		int val;
    		ListNode next;
    		ListNode(int x) { val = x; }
    	}
    
    }
    

    面试题2.3:实现一个算法,删除单向链表中间的某个结点,假定你只能访问该结点。

      思路:因为是单向链表,所以不知道一个结点的前一个结点,所以当这个结点是最后一个的时候,无解

         只要把要删除的结点的下一个结点的数据复制到这个结点即可。

    import java.util.*;
     
    /*
    public class ListNode {
        int val;
        ListNode next = null;
     
        ListNode(int val) {
            this.val = val;
        }
    }*/
    public class Remove {
        public boolean removeNode(ListNode pNode) {
            // write code here
            if(pNode == null || pNode.next == null)
                return false;
            ListNode nextNode = pNode.next;//取得要删除结点的下一个结点
            pNode.val = nextNode.val;
            pNode.next = nextNode.next;
            return true;
        }
    }
    

     面试题2.4:编写代码,以给定值x为基准讲链表分割成两部分,所有小于x的结点排在大于或者等于x的结点之前。

    package cc150;
    
    public class Partition {
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		ListNode Node1 = new ListNode(5);
    		ListNode Node2 = new ListNode(4);
    		ListNode Node3 = new ListNode(3);
    		ListNode Node4 = new ListNode(2);
    		ListNode Node5 = new ListNode(1);
    		Node1.next = Node2;
    		Node2.next = Node3;
    		Node3.next = Node4;
    		Node4.next = Node5;
    		ListNode temp = partition(Node1,3);
    		
    		while(temp != null){
    			System.out.println(temp.val);
    			temp = temp.next;
    		}
    	}
    	
    	 public static ListNode partition(ListNode pHead, int x) {
    		 // write code here
    		 ListNode beforeStart = null;	//记录链表的头结点
    		 ListNode afterStart = null;		//记录链表的头结点
    		 ListNode beforeEnd = null;
    		 ListNode afterEnd = null;
    		 
    		 ListNode pNext = pHead;
    		 while(pNext != null){
    			
    			 if(pNext.val < x){
    				 if(beforeStart == null){
    					 beforeStart = pNext;
    					 beforeEnd = pNext;
    				 }else{
    					 beforeEnd.next = pNext;
    					 beforeEnd = beforeEnd.next;
    				 }
    			 }else{
    				 if(afterStart == null){
    					 afterStart = pNext;
    					 afterEnd = pNext;
    				 }else{
    					 afterEnd.next = pNext;
    					 afterEnd = afterEnd.next;
    				 }
    			 }
    			 pNext = pNext.next;
    		 }
    		 
    		 //切记断掉after最后一个元素的next,不然会形成环
    		 if(afterEnd != null)
    			 afterEnd.next = null;
    		 
    		 //如果beforeStart为null,返回afterStart头结点
    		 if(beforeStart == null)
    			 return afterStart;
    		
    		 beforeEnd.next = afterStart;
    		 return beforeStart;
    	 }
    	 
    	 public static class ListNode {
    			int val;
    			ListNode next;
    			ListNode(int x) { val = x; }
    		}
    
    }
    

     面试题2.5:给定两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表首部。编写函数对这两个整数求和,并用链表形式返回结果。

      进阶:假设这些数位是正向存放的,请再做一遍。

    package cc150;
    
    import cc150.Partition.ListNode;
    
    public class Plus {
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		ListNode Node1 = new ListNode(7);
    		ListNode Node2 = new ListNode(2);
    		ListNode Node3 = new ListNode(3);
    		Node1.next = Node2;
    		Node2.next = Node3;
    
    		ListNode Node4 = new ListNode(4);
    		ListNode Node5 = new ListNode(5);
    		ListNode Node6 = new ListNode(6);
    		ListNode Node7 = new ListNode(7);
    		Node4.next = Node5;
    		Node5.next = Node6;
    		Node6.next = Node7;
    		
    		ListNode temp = plusAB(Node1,Node4);
    		System.out.println(temp.val);
    		while(temp !=null){
    			System.out.print(temp.val);
    			temp = temp.next;
    		}
    	}
    	
    	public static ListNode plusAB(ListNode a, ListNode b) {
            // write code here
    		if(a == null && b == null)
    			return null;
    		int carry = 0;
    		ListNode result_temp = new ListNode(0);
    		ListNode result = result_temp;
    		while(a != null && b != null){
    			int value = a.val + b.val + carry;
    			
    			if(value>=10){
    				result_temp.next = new ListNode(value-10);
    				carry = 1;
    			}else{
    				result_temp.next = new ListNode(value);
    				carry = 0;
    			}
    			result_temp = result_temp.next;
    			a = a.next;
    			b = b.next;
    		}
    		if(a != null){
    			result_temp.next = new ListNode(a.val+carry);
    			result_temp.next.next = a.next;
    		}
    		else if(b != null){
    			result_temp.next = new ListNode(b.val+carry);
    			result_temp.next.next = b.next;
    		}
    		else if(carry == 1){
    			result_temp.next = new ListNode(carry);
    		}
    		
    		return result.next;
        }
    	
    	 public static class ListNode {
    			int val;
    			ListNode next;
    			ListNode(int x) { val = x; }
    		}
    
    }
    

    面试题2.6:给定一个有环链表,实现一个算法返回环路的开头结点。

    package cc150;
    
    import cc150.Plus.ListNode;
    
    public class FindBeginning {
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		ListNode Node1 = new ListNode(1);
    		ListNode Node2 = new ListNode(2);
    		ListNode Node3 = new ListNode(3);
    		ListNode Node4 = new ListNode(4);
    		ListNode Node5 = new ListNode(5);
    		ListNode Node6 = new ListNode(6);
    		ListNode Node7 = new ListNode(7);
    		ListNode Node8 = new ListNode(8);
    		ListNode Node9 = new ListNode(9);
    		
    		Node1.next = Node2;
    		Node2.next = Node3;
    		Node3.next = Node4;
    		Node4.next = Node5;
    		Node5.next = Node6;
    		Node6.next = Node7;
    		Node7.next = Node8;
    		Node8.next = Node9;
    		Node9.next = Node4;
    		
    		System.out.println(findBeginning(Node1).val);
    	}
    	
    	public static ListNode findBeginning(ListNode head){
    		ListNode slow = head;
    		ListNode fast = head;
    		//slow移动一步,fast移动两步,链表到头或者碰撞的时候停止
    		while(fast != null && fast.next != null){
    			slow = slow.next;
    			fast = fast.next.next;
    			if(slow == fast)
    				break;
    		}
    		//如果是链表到头,没有环路
    		if(fast == null || fast.next == null)
    			return null;
    		//将slow指向链表头部,fast指向碰撞处,两者同时移动,必回在环路起点相遇
    		slow = head;
    		while(slow != fast){
    			slow = slow.next;
    			fast = fast.next;
    		}
    		return fast;
    	}
    	
    	 public static class ListNode {
    		int val;
    		ListNode next;
    		ListNode(int x) { val = x; }
    	}
    
    }
    

    面试题2.7: 编写一个函数,检查链表是否为回文。

      CC150第一种解法:反转并比较

    import java.util.*;
     
    /*
    public class ListNode {
        int val;
        ListNode next = null;
     
        ListNode(int val) {
            this.val = val;
        }
    }*/
    public class Palindrome {
        public boolean isPalindrome(ListNode pHead) {//反转并比较,CC150第一种解法
            // write code here
            if(pHead == null || pHead.next == null)
                return true;
            ListNode slow,fast;     //快慢指针法查找链表的中心
            slow = fast = pHead;
            while(fast != null && fast.next != null){
                slow = slow.next;
                fast = fast.next.next;
            }
            if(fast != null){    //链表个数奇数个
                slow.next = reverseList(slow.next);
                slow = slow.next;   //去掉中间的数
            }else{
                slow = reverseList(slow);
            }
            while(slow != null){
                if(pHead.val != slow.val)
                    return false;
                slow = slow.next;
                pHead = pHead.next;
            }
            return true;
        }
         
        public ListNode reverseList(ListNode head) {
            if(head ==null){
                return null;
            }
            Stack<ListNode> stack = new Stack<ListNode>();
            ListNode current = head;
            while(current != null){
                stack.add(current);
                current = current.next;
            }
            head = stack.pop();
            current = head;
            while(stack.empty() != true){
                current.next = stack.pop();
                current = current.next;
            }
            current.next = null;  //Memory Limit Exceeded
            return head;
        }
    }
    
  • 相关阅读:
    项目无法运行iPhone5模拟器
    多线程下载图片,滑动tableView崩溃--资源抢夺问题
    提醒事项 1. 冥想TX 2.下班路上听歌激励自己 3. 不戴眼镜 4. 困难任务拆解
    AutoLayout性能不如frame
    Tunnelblick 覆盖安装失败
    weakSelf 和 strongSelf
    动画
    4/16 近期状态
    知乎live 我的读书经验 总结
    C语言-第23课
  • 原文地址:https://www.cnblogs.com/tonglin0325/p/5864224.html
Copyright © 2011-2022 走看看