剑指Offer面试题37两个链表的第一个公共结点,面试题38数字在排序数组中出现的次数

来源:互联网 发布:qq加好友软件 编辑:程序博客网 时间:2024/05/18 00:35

面试题37:两个链表的第一个公共结点

输入两个单向链表,输出公共节点。注意了,两个单链表如果有公共节点,形状肯定是Y型的,因为每个结点都只有一个next结点,这个公共节点之后不会有分支了。
思路:假如链表长度分别为m和n,采用固定一个链表的第一个结点,遍历另一个链表的方法的复杂度为O(m*n),有点大了,所以换个思路,既然公共节点之后的结点都是共有的,两个链表的长度差别只在公共节点之前,所以可以先得出两个链表的长度之差d,较长的链表先走d步,然后再同时遍历两个链表,直到公共节点即可。
Java实现如下:

class ListNode{    int data;    ListNode next;    public ListNode(int data) {        this.data = data;        this.next = null;    }}public class FindFirstCommonNode {    // 核心    static ListNode findFirstCommonNode(ListNode list1, ListNode list2){        int len1 = getLen(list1);        int len2 = getLen(list2);        int diff = 0;        ListNode longList = null;        ListNode shortList = null;        if(len1 != 0 && len2 != 0){            if(len1 > len2){                diff = len1 - len2;                longList = list1;                shortList = list2;            }else{                diff = len2 - len1;                longList = list2;                shortList = list1;            }            for(int i = diff; i > 0;i--){                longList = longList.next;            }            while(longList != null && shortList != null && longList != shortList){                longList = longList.next;                shortList = shortList.next;            }        }        return longList;    }    // 求链表长度    static int getLen(ListNode list){        int len = 0;        while(list != null){            len++;            list = list.next;        }        return len;    }    // main    public static void main(String[] args) {        ListNode a1 = new ListNode(1);        ListNode a2 = new ListNode(2);        ListNode a3 = new ListNode(3);        ListNode a4 = new ListNode(4);        ListNode b1 = new ListNode(1);        ListNode b2 = new ListNode(2);        a1.next = a2;        a2.next = a3;        a3.next = a4;        b1.next = b2;        b2.next = a3;        System.out.println(findFirstCommonNode(a1, b1).data);    }}

面试题38:数字在排序数组中出现的次数

例如输入{1,2,3,3,3,3,4,5}和3,由于3出现了4次,输出4。
思路:顺序查找复杂度为O(n),我们有O(logn)的方法,就是用二分查找,找到该数字第一次出现和最后一次出现的位置即可,详见代码。
Java实现如下:

public class GetNumberOfK {    // 二分法找第一个出现的k    static int getFirstK(int[] arr, int k, int start, int end){        if(start > end)            return -1;        int mid = (start + end) / 2;        if(arr[mid] == k){            if((mid > 0 && arr[mid-1] != k) || mid == 0)                return mid;            else                end = mid - 1;        }else if(arr[mid] > k)            end = mid - 1;        else            start = mid + 1;        return getFirstK(arr, k, start, end);    }    // 二分法找最后一个k    static int getLastK(int[] arr, int k, int start, int end){        if(start > end)            return -1;        int mid = (start + end) / 2;        if(arr[mid] == k){            if((mid < arr.length-1 && arr[mid+1] != k) || mid == arr.length-1)                return mid;            else                start = mid + 1;        }else if(arr[mid] < k)            start = mid + 1;        else            end = mid - 1;        return getLastK(arr, k, start, end);    }    // 计算个数    static int getNumberOfK(int[] arr, int k){        int number = 0;        if(arr != null && arr.length > 0){            int first = getFirstK(arr, k, 0, arr.length-1);            int last = getLastK(arr, k, 0, arr.length-1);            if(first >= 0 && last >= 0)                number = last - first + 1;        }        return number;    }    public static void main(String[] args) {        int[] arr = {1,2,3,3,3,3,4,5};        int k = 3;        System.out.println(getNumberOfK(arr, k));    }}
阅读全文
0 0
原创粉丝点击