1. 程式人生 > 其它 >nowcoder-oj【面試高頻TOP榜單-簡單難度(4)5道】

nowcoder-oj【面試高頻TOP榜單-簡單難度(4)5道】

1、NC13二叉樹的最大深度

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode類 
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        // write code here
} }

實現

遞迴

import java.util.*;

/*
 * public class TreeNode {
 *   int val = 0;
 *   TreeNode left = null;
 *   TreeNode right = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param root TreeNode類 
     * @return int整型
     */
    public int maxDepth (TreeNode root) {
        if(root == null
){ return 0; } int maxL = 0; //左子樹最大深度 int maxR = 0; //右子樹最大深度 if(root.left != null){ maxL = maxDepth(root.left); } if(root.right != null){ maxR = maxDepth(root.right); } int max = maxL>maxR ? maxL+1 : maxR+1;
return max; } }

其他

【資料結構和演算法】遞迴,BFS,DFS等3種實現方式_牛客部落格 (nowcoder.net)

2、NC70單鏈表的排序

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

public class Solution {
    /**
     * 
     * @param head ListNode類 the head node
     * @return ListNode類
     */
    public ListNode sortInList (ListNode head) {
        // write code here
    }
}

實現

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 * }
 */

import java.util.ArrayList;
import java.util.Comparator;
public class Solution {
    /**
     * 
     * @param head ListNode類 the head node
     * @return ListNode類
     */
    public ListNode sortInList (ListNode head) {
        //思路1:單鏈表構造為二叉樹(小於根左子,大於根右子),中序遍歷(左根右),迭代
        //思路2:遍歷連結串列,取出資料構成陣列/列表,陣列/列表排序,重構連結串列
        if(head == null || head.next == null){
            return head;
        }
        ArrayList<Integer> list = new ArrayList<>();
        list.add(head.val);
        while(head.next != null){
            list.add(head.next.val);
            head = head.next;
        }
        list.sort(Comparator.naturalOrder()); //自然順序,即升序排序
        ListNode res = new ListNode(list.get(0));
        ListNode move = res;
        for(int i=1; i<list.size(); i++){
            ListNode temp = new ListNode(list.get(i));
            move.next = temp;
            move = move.next;
        }
        return res;
    }
}

其他1

    //參考1:值排序,不是真正做到連結串列排序,直接遍歷整個連結串列,用一個數組儲存所有的val,然後進行排序,最後將排序完的值賦值給連結串列
    public ListNode sortInList (ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ArrayList<Integer> list = new ArrayList<>();
        ListNode temp = head;
        while(temp != null){
            list.add(temp.val);
            temp = temp.next;
        }
        list.sort( (a,b)->{return a-b;} ); //lambda表示式
        ListNode temp2 = head;
        int i = 0;
        while(temp2 != null){
            temp2.val = list.get(i++);
            temp2 = temp2.next;
        }
        return head;
    }

其他2

    //參考2:先利用快慢指標找出連結串列的中點,然後分為兩個連結串列,一直分,知道無法分為止,然後自底而上排序歸併
    public ListNode sortInList (ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        //利用快慢指標找到中點
        ListNode slow = head;
        ListNode fast = head.next;
        while(fast!=null && fast.next!=null){
            slow = slow.next;
            fast = fast.next.next;
        }
        //分割為兩個連結串列
        ListNode newHead = slow.next;
        slow.next = null;
        //利用遞迴將兩個連結串列繼續分割
        ListNode left = sortInList(head);
        ListNode right = sortInList(newHead);
        ListNode lHead = new ListNode(-1); //
        ListNode res = lHead; //
        //歸併排序
        while(left!=null && right!=null){
            if(left.val < right.val){
                lHead.next = left;
                left = left.next;
            }else{
                lHead.next = right;
                right = right.next;
            }
            lHead = lHead.next;
        }
        //判斷左右連結串列是否為空
        lHead.next = left!=null?left:right;
        return res.next;
    }

3、NC62平衡二叉樹

public class Solution {
    public boolean IsBalanced_Solution(TreeNode root) {
        
    }
}

參考1

public class Solution {
    
    //參考1:平衡二叉樹的左右子樹也是平衡二叉樹,那麼所謂平衡就是左右子樹的高度差不超過1
    public boolean IsBalanced_Solution(TreeNode root) {
        return depth(root) != -1;
    }
    
    public int depth(TreeNode root){
        if(root == null){
            return 0;
        }
        int left = depth(root.left);
        if(left == -1){
            return -1; //如果發現子樹不平衡之後就沒有必要進行下面的高度的求解了
        }
        int right = depth(root.right);
        if(right == -1){
            return -1; //如果發現子樹不平衡之後就沒有必要進行下面的高度的求解了
        }
        if(left-right<-1 || left-right>1){ //Math.abs(left-right) > 1
            return -1;
        }else{
            return 1 + (left>right?left:right); //Math.max(left,right)
        }
    }
    
}

參考2

public class Solution {
    
    //參考2:與參考1解法差不多,本質一樣
    //在使用遞迴求的深度後,其實可以在遞迴中,直接判斷左右子樹的差值。這時候就相當於多一個變數。
    boolean isBalanced = true;
    
    public boolean IsBalanced_Solution(TreeNode root) {
        depth(root);
        return isBalanced;
    }
    
    public int depth(TreeNode root){
        if(root == null){
            return 0;
        }
        int left = depth(root.left);
        if(left == -1){
            return -1; //剪枝(不符合條件的,直接一直向上返回,沒必要還去計算深度)
        }
        int right = depth(root.right);
        if(right == -1){
            return -1; //剪枝(不符合條件的,直接一直向上返回,沒必要還去計算深度)
        }
        if(right-left>1 || left-right>1){ 
            isBalanced = false;
            return -1;
        }else{
            return left>right ? left+1 : right+1; 
        }
    }
    
}

4、NC73陣列中出現次數超過一半的數字

public class Solution {
    public int MoreThanHalfNum_Solution(int [] array) {
        
    }
}

實現

import java.util.HashMap;

public class Solution {
    
    public int MoreThanHalfNum_Solution(int [] array) {
        int length = array.length;
        if(length == 0){
            return -1;
        }
        if(length == 1){
            return array[0];
        }
        
        int half = 0;
        if(length%2 == 0){
            half = length/2;
        }else{
            half = length/2+1;
        }
        
        int res = 0;
        HashMap<Integer, Integer> map = new HashMap<>();
        
        for(int i=0; i<length; i++){
            int key = array[i];
            if(!map.containsKey(key)){
                map.put(key, 1);
            }else{
                int value = map.get(key);
                value++;
                if(value >= half){
                    res = key;
                    break;
                }
                map.put(key, value);
            }
            
        }
        
        return res;
    }
    
}

其他1

/*
用一般的排序也可以完成這道題目,但是如果那樣完成的話就可能太簡單了。
用preValue記錄上一次訪問的值,count表明當前值出現的次數,
如果下一個值和當前值相同那麼count++;如果不同count--,
減到0的時候就要更換新的preValue值了,
因為如果存在超過陣列長度一半的值,那麼最後preValue一定會是該值。
*/
public class Solution {
    
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array == null || array.length == 0){
            return 0;
        }
        int preValue = array[0];
        int count = 1;
        for(int i=1; i<array.length; i++){
            if(array[i] == preValue){
                count++;
            }else{
                count--;
                if(count == 0){
                    preValue = array[i];
                    count = 1;
                }
            }
        }
        int num = 0;//需要判斷是否真的是大於1半數,這一步驟是非常有必要的,因為我們的上一次遍歷只是保證如果存在超過一半的數就是preValue,但不代表preValue一定會超過一半
        for(int i=0; i<array.length; i++){
            if(array[i] == preValue){
                num++;
            }
        }
        return (num > array.length/2) ? preValue : 0;
    }
    
}

其他2

其他3

其他4

同我的解決思路

import java.util.*;

public class Solution {
    
    public int MoreThanHalfNum_Solution(int [] array) {
        if(array.length == 0){
            return 0;
        }
        
        int len = array.length;
        int threshold = len/2;
        
        Map<Integer,Integer> map = new HashMap<>();
        for(int i = 0; i < len; i++){
            if(!map.keySet().contains(array[i])){
                map.put(array[i],1);
            }else{
                map.put(array[i],map.get(array[i])+1);
            }
        }
        for(Integer key: map.keySet()){
            if(map.get(key) > threshold){
                return key;
            }
        }
        
        return 0;
    }
    
}

5、NC112進位制轉換

import java.util.*;


public class Solution {
    /**
     * 進位制轉換
     * @param M int整型 給定整數
     * @param N int整型 轉換到的進位制
     * @return string字串
     */
    public String solve (int M, int N) {
        // write code here
    }
}

參考1

    //演算法思路: 除N取餘,然後倒序排列,高位補零。
    public String solve (int M, int N) {
        if(M == 0){
            return "0";
        }
        String baseStr = "0123456789ABCDEF";
        StringBuffer sb = new StringBuffer();
        boolean flag = false;
        if(M < 0){
            flag = true;
            M = -M;
        }
        while(M != 0){
            sb.append(baseStr.charAt(M % N));
            M /= N;
        }
        if(flag){
            sb.append("-");
        }
        return sb.reverse().toString();
    }

參考2

參考1的解釋