nowcoder-oj【面试高频TOP榜单-简单难度(3)5道】

1、NC66 两个链表的第一个公共结点

 

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

    ListNode(int val) {
        this.val = val;
    }
}*/
public class Solution {
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
    }
}
View Code

 

    //0(未实现,4/8 组用例通过)
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null || pHead2==null){ 
            //两个空链表
            return null;
        }
        if(pHead1.next==null && pHead2.next==null && pHead1.val==pHead2.val){ 
            //两个单节点链表,且节点值相等
            return pHead1;
        }
        if(pHead1.next==null && pHead2.next==null && pHead1.val!=pHead2.val){
            //两个单节点链表,且节点值不等
            return null;
        }
        //-----------------------------------------逻辑实现有点问题
        ListNode res = pHead1;
        while(pHead1.next != null){
            while(pHead2.next != null){
                if(pHead1 == pHead2){
                    ListNode temp = res;
                    res.next = pHead1;
                    temp = res.next;
                }
                pHead2 = pHead2.next;
            }
            pHead1 = pHead1.next;
        }
        return res.next;
        //-----------------------------------------
    }
View Code 

参考1

 

 

    //参考1
    public ListNode FindFirstCommonNode(ListNode pHead1, ListNode pHead2) {
        if(pHead1==null || pHead2==null){ 
            return null;
        }
        ListNode p1 = pHead1;
        ListNode p2 = pHead2;
        while(p1 != p2){
            p1 = p1.next;
            p2 = p2.next;
            if(p1 != p2){
                if(p1 == null){
                    p1 = pHead2;
                }
                if(p2 == null){
                    p2 = pHead1;
                }
            }
        }
        return p1;
    }

参考2

【宫水三叶の剑指精选】一题五解 :「朴素解法」&「栈解法」&「Set 解法」&「差值法」&「等值法」_牛客博客 (nowcoder.net)

 

 

    //参考2:朴素解法
    public ListNode FindFirstCommonNode(ListNode a, ListNode b) {
        for (ListNode h1=a; h1!=null; h1=h1.next) {
            for (ListNode h2=b; h2!=null; h2=h2.next) {
                if (h1 == h2){
                    return h1;
                }
            }
        }
        return null;
    }

 

 

    //参考3:栈解法
    public ListNode FindFirstCommonNode(ListNode a, ListNode b) {
        Deque<ListNode> d1 = new ArrayDeque<>(), d2 = new ArrayDeque<>();
        while (a != null) {
            d1.add(a);
            a = a.next;
        }
        while (b != null) {
            d2.add(b);
            b = b.next;
        }
        ListNode ans = null;
        while (!d1.isEmpty() && !d2.isEmpty() && d1.peekLast()==d2.peekLast()) {
            ans = d1.pollLast();
            d2.pollLast();
        }
        return ans;
    }

    //参考4:Set集合解法
    public ListNode FindFirstCommonNode(ListNode a, ListNode b) {
        Set<ListNode> set = new HashSet<>();
        while (a != null) {
            set.add(a);
            a = a.next;
        }
        while (b != null && !set.contains(b)){
            b = b.next;
        }
        return b;
    } 

2、NC32 求平方根

import java.util.*;


public class Solution {
    /**
     * 
     * @param x int整型 
     * @return int整型
     */
    public int sqrt (int x) {
        // write code here
    }
}

参考1

 

    //参考1:二分查找
    public int sqrt(int x) {
        if (x <= 0) {
            return 0;
        }
        int left = 1;
        int right = x;
        while (true) {
            int middle = (left + right) >> 1;
            if (middle<= x/middle && (middle+1) > x/(middle+1)) {
                return (int) middle;
            } else if (middle < x/middle) {
                left = middle + 1;
            } else {
                right = middle - 1;
            }
        }
    }

参考2

    //参考2:牛顿迭代
    public int sqrt(int x) {
        if (x <= 0) {
            return 0;
        }
        long r = x;
        while (r > x/r) {
            r = (r+x/r) / 2;
        }
        return (int) r;
    }

参考3

    //参考3
    public int sqrt(int x) {
         if (x <= 0) {
             return 0;
         }
         int i = 1;
         for (i=1; i<=x; i++) {
             if (i*i<=x && (i+1)*(i+1)>x) {
                 break;
             }
         }
         return i;
    } 

3、NC48 在旋转过的有序数组中寻找目标值

 

 

 1 import java.util.*;
 2 
 3 
 4 public class Solution {
 5     /**
 6      * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 7      *
 8      * 
 9      * @param nums int整型一维数组 
10      * @param target int整型 
11      * @return int整型
12      */
13     public int search (int[] nums, int target) {
14         // write code here
15     }
16 }

 实现

    //0
    public int search (int[] nums, int target) {
        if(nums.length == 1 && nums[0] != target){
            return -1;
        }
        if(nums.length == 1 && nums[0] == target){
            return 0;
        }
        for(int i=0; i<nums.length; i++){
            if(nums[i] == target){
                return i;
            }
        }
        return -1;
    }

 

 其他

 

 

 

 

 

 

    //参考1:二分查找
     public int search (int[] nums, int target) {
        if (nums == null || nums.length < 1) {
            return -1;
        }
        if (nums.length == 1) {
            return nums[0] == target ? 0 : -1;
        }
        int start = 0;
        int end = nums.length - 1;
        while (end >= start) {
            // 找到 左右指针中间位置
            int mid = (end + start) >> 1;
            if (nums[mid] == target) {
                return mid;
            }
            // 在左侧升序数组中
            if (nums[0] <= nums[mid]) {
                // 在开头和 mid 之间,那么 右指针则为 mid -1
                if (target >= nums[0] && target < nums[mid]) {
                    end = mid -1;
                } else {
                    start = mid + 1;
                }
            } else {
                // 如果在 mid 和end 之前,更新 start 为 mid = 1
                if (target > nums[mid] && target <= nums[end]) {
                    start = mid + 1;
                } else {
                    end = mid - 1;
                }
            }
        }
        return -1;
    }
View Code

 

4、NC90 包含min函数的栈

import java.util.Stack;

public class Solution {

    
    public void push(int node) {
        
    }
    
    public void pop() {
        
    }
    
    public int top() {
        
    }
    
    public int min() {
        
    }
}

 

 

参考

 

 

 同步辅助栈

import java.util.Stack;

public class Solution {
    Stack<Integer> stackTotal = new Stack<Integer>();
    Stack<Integer> stackLittle = new Stack<Integer>();

    public void push(int node) {
        stackTotal.push(node);
        if(stackLittle.empty()){
            stackLittle.push(node);
        }else{
            if(node <= stackLittle.peek()){
                stackLittle.push(node);
            }else{
                stackLittle.push(stackLittle.peek());
            }
        }
    }

    public void pop() {
        stackTotal.pop();
        stackLittle.pop();
    }

    public int top() {
        return stackTotal.peek();
    }

    public int min() {
        return stackLittle.peek();
    }
}

5、NC7 买卖股票的最好时机(股票一次交易)

 

 

import java.util.*;


public class Solution {
    /**
     * 
     * @param prices int整型一维数组 
     * @return int整型
     */
    public int maxProfit (int[] prices) {
        // write code here
    }
}

实现

import java.util.*;


public class Solution {
   
    /*
        分析:
            从示例来看,明显数组第一个元素是买入价格,而不是买后的第一天
            prices[0]为买入当天(第0天)的价格,即买入价格
            在数组prices中找到除了prices[0]外的最大一个元素prices[i]
            最大收益=prices[i]-prices[0]
            PS:百度:当天买入的股票当天是不可以卖出的
    */
    public int maxProfit (int[] prices) {
        int length = prices.length;
        if(length <=1){
            return 0;
        }
        /*
        int take = prices[0];
        int maxSell = prices[0];
        for(int i=1; i<length; i++){
            if(prices[i] >= maxSell){
                maxSell = prices[i];
            }
        }
        return maxSell-take;
        */
        
        /*
            仅9/19 组用例通过,复盘发现,审题错了
                并不是必须在第一个元素这一天买入
                可以在非最后一个元素之前的任一天买入
                在买入这一元素之后,至数组最后一个元素(包含)找一个最大的价格卖出即可
        */
        int max = 0;
        for(int i=0; i<length-1; i++){
            int buy = prices[i];
            for(int j=i+1; j<length; j++){
                int sell = prices[j];
                if(sell-buy > max){
                    max = sell-buy;
                }
            }
        }
        return max;
    }
    
    
}

其他

【数据结构和算法】动态规划,双指针,单调栈等6种解决方式_牛客博客 (nowcoder.net)

 

posted @ 2021-09-18 13:37  yub4by  阅读(48)  评论(0)    收藏  举报