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

1、NC19 子数组的最大累加和问题

 

复制代码
import java.util.*;


public class Solution {
    /**
     * max sum of the subarray
     * @param arr int整型一维数组 the array
     * @return int整型
     */
    public int maxsumofSubarray (int[] arr) {
        // write code here
        
        //0 (算法时间复杂度过大 导致仅3/7组用例通过)
        /*
        int length = arr.length;
        if(length == 1){
            return arr[0];
        }
        int max = 0;
        for(int i=0; i<length-1; i++){
            int sum = arr[i];
            for(int j=i+1; j<length; j++){
                sum = sum + arr[j];
                if(sum > max){
                    max = sum;
                }
            }
        }
        for(int i=0; i<length; i++){
            if(arr[i] > max){
                max = arr[i];
            }
        }
        return max;
        */
        
        //参考1:动态规划
        /*
        int length = arr.length;
        int[] dp = new int[length];
        dp[0] = arr[0]; //边界条件
        int max = dp[0];
        for(int i=1; i<length; i++){
            dp[i] = Math.max(dp[i-1], 0) + arr[i]; //转移公式
            max = Math.max(max, dp[i]); //记录最大值
        }
        return max;
        */
        
        //参考2:动态规划改进
        /*
        int length = arr.length;
        int cur = arr[0];
        int max = cur;
        for(int i=1; i<length; i++){
            cur = Math.max(cur, 0) + arr[i]; 
            max = Math.max(max, cur);
        }
        return max;
        */
        
        //参考3
        int sum = 0, max = 0;
        for(int i=0; i<arr.length; i++){
            sum = Math.max(0, arr[i]+sum);
            max = Math.max(max, sum);
        }
        return max;
        
        
        
    }
}
View Code
复制代码

 

 


2、NC4 判断链表中是否有环

 

 

复制代码
/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
    public boolean hasCycle(ListNode head) {
        
        //0 (自拟算法有点问题 13/15 组用例通过)
        /*
        if(head == null){
            return false;
        }
        ListNode outer = head;
        ListNode inner = head;
        while(outer.next != null){
            outer = outer.next;
            while(inner.next != null){
                if(inner == outer){
                    return true;
                }else{
                    inner = inner.next;
                }
            }
        }
        return false;
        */
        
        //参考1:快慢指针
        /*
        if(head == null){
            return false;
        }
        ListNode fast = head;
        ListNode slow = head;
        while(fast!=null && fast.next!=null){
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow){
                return true;
            }
        }
        return false;
        */
        
        //参考2:将链表存放到Set集合中(编译错误,OJ不支持Set??)
        //把节点存放到集合set中,每次存放的时候判断当前节点是否存在,如果存在,说明有环,直接返回true
        /*
        Set<ListNode> set = new HashSet<ListNode>();
        while(head != null){
            if(set.contains(head)){
                return true;
            }else{
                set.add(head);
                head = head.next;
            }
        }
        return false;
        */
        
        
        //参考3:逐个删除链表的结点
        if (head == null || head.next == null){
            return false; //如果head为空,或者他的next指向为空,直接返回false
        }
        if (head.next == head){
            return true; //如果出现head.next = head表示有环
        }
        ListNode nextNode = head.next;
        head.next = head; //当前节点的next指向他自己,相当于把它删除了
        return hasCycle(nextNode); //然后递归,查看下一个节点
        
        
    }
}
View Code
复制代码

 

 

  


 

 

 

 

 

3、NC22 合并两个有序的数组

 

 

 

 

复制代码
public class Solution {
    public void merge(int A[], int m, int B[], int n) {
        
        
        //0
        //AB都有序,A的空间=m+n,将B合并到A中并保持A仍有序
        /*
        int[] C = new int[m+n];
        for(int i=0; i<m; i++){
            C[i] = A[i];
        }
        for(int j=0; j<n; j++){
            C[m+j] = B[j];
        }
        for(int i=0; i<m+n-1; i++){ //  双层循环实现冒泡排序
            for(int j=0; j<m+n-i-1; j++){
                if(C[j+1] < C[j]){ //  <升序,>降序
                    int temp = C[j];
                    C[j] = C[j+1];
                    C[j+1] = temp;
                }
            }
        }
        for(int i=0; i<m+n; i++){
            A[i] = C[i];
        }
        */
        
        //参考1:归并排序系
        //要合并到数组A上,自然是不适合从小到大遍历,这样会在A数组上移动次数太多,所以从大到小遍历,按归并排序的套路写
        /*
        int i=m-1, j=n-1, index=m+n-1;
        while (i>=0 && j>=0) {
            if (A[i] > B[j]) {
                A[index--] = A[i--];
            } else {
                A[index--] = B[j--];
            }
        }
        while (j>=0) {
            A[index--] = B[j--];
        }
        */
        
        //参考2:NC官方实现
        int a = m-1;
        int b = n-1;
        for(int i=m+n-1; i>=0; i--){ //需要填m+n次
            if(b<0 || (a>=0&&A[a]>=B[b]) ){  //B数组中的数全部用完了就填A数组中的数 a数组中的数没有用完,并且A数组的数大
                A[i]=A[a];
                a--;
            }else{
                A[i] = B[b];
                b--;
            }
        }

        
    }
}
View Code
复制代码

 

 

 

4、NC52 括号序列

 

 

复制代码
import java.util.*;


public class Solution {
    /**
     * 
     * @param s string字符串 
     * @return bool布尔型
     */
    public boolean isValid (String s) {
        // write code here
        
        //参考1:字符替换
        /*
        boolean flag = true;
        while(flag){
            int length = s.length();
            s = s.replace("()", "");
            s = s.replace("[]", "");
            s = s.replace("{}", "");
            if(length == s.length()){
                flag = false;
            }
        }
        return s.length() == 0; //'()','[]','{}'替换为'',最后字符串为空就true
        */
        
        //参考2:栈
        Stack<Character> stack = new Stack<>();
        char[] charArr = s.toCharArray();
        for(char c: charArr){
            //如果是左括号,就把他们对应的右括号压栈
            if(c == '('){
                stack.push(')');
            }else if(c == '['){
                stack.push(']');
            }else if(c == '{'){
                stack.push('}');
            }else if(stack.isEmpty() || stack.pop()!=c){
                //否则就只能是右括号。
                //1,如果栈为空,说明括号无法匹配。
                //2,如果栈不为空,栈顶元素就要出栈,和这个右括号比较。
                //如果栈顶元素不等于这个右括号,说明无法匹配,
                //直接返回false。
                return false;
            }
        }
        //最后如果栈为空,说明完全匹配,是有效的括号。
        //否则不完全匹配,就不是有效的括号
        return stack.isEmpty();
        
    }
}
View Code
复制代码

 

 

 

 

 

 

 

 

 


 

 


 

 

 

5、NC14 按之字形顺序打印二叉树

 

 

 

 参考1

 

 

复制代码
import java.util.ArrayList;
import java.util.Queue;
import java.util.LinkedList;
import java.util.Stack;

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

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public ArrayList< ArrayList<Integer> > Print(TreeNode pRoot) {
        
        //参考1
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if(pRoot == null) return result;
        Stack<TreeNode> tmp = new Stack<>();
        Stack<TreeNode> tmp1 = new Stack<>();
        tmp.add(pRoot);
        while(tmp.size() > 0 || tmp1.size() > 0) {
            ArrayList<Integer> flood = new ArrayList<>();
            if(tmp.size() > 0) {
                int size = tmp.size();
                for(int i=0; i<size; i++) {
                    TreeNode pop = tmp.pop();
                    flood.add(pop.val);
                    if(pop.left != null) {
                        tmp1.add(pop.left);
                    }
                    if(pop.right != null) {
                        tmp1.add(pop.right);
                    }
                }
                result.add(flood);
                continue;
            }
            if(tmp1.size() > 0) {
                int size = tmp1.size();
                for(int i=0; i<size; i++) {
                    TreeNode pop = tmp1.pop();
                    flood.add(pop.val);
                    if(pop.right != null) {
                        tmp.add(pop.right);
                    }
                    if(pop.left != null) {
                        tmp.add(pop.left);
                    }
                }
                result.add(flood);
                continue;
            }
        }
        return result;
        
    }

}
View Code
复制代码

 


 参考2&3

复制代码
import java.util.ArrayList;
import java.util.Stack;

public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
        if(pRoot == null)return res;
        Stack<Integer> stack = new Stack<Integer>();//stack仅用于偶数层翻转val
        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();//queue是奇偶共用
        queue.add(pRoot);
        int layer = 1;//层数用layer (区别于深度depth = layer-1)
        while(!queue.isEmpty()){
            ArrayList<Integer> list = new ArrayList<Integer>();//新建行
            int size = queue.size();//出本层前记录size,不然难以做到层数的切分  //提前写出来,因为size会变
            for(int i=0; i<=size-1; ++i){
                TreeNode node = queue.get(0);//一定要新建node副本,不然是引用会变
                queue.remove(0);
                if(layer % 2 == 1){
                    list.add(node.val);
                }
                else{//偶数行,需要栈翻转
                    stack.push(node.val);
                }
                if(node.left != null)queue.add(node.left);
                if(node.right != null)queue.add(node.right);
            }
            while(!stack.isEmpty()){
                list.add(stack.pop());//偶数层一次性添加,奇数层一个个添加
            }
            res.add(list);
            ++layer;//本层结束,层数加一
        }
        return res;
    }
}//时间、空间复杂度,都是树的规模 O(N)
View Code
复制代码

 

 

 

 

复制代码
import java.util.ArrayList;

public class Solution {//方法2和方法1相比,代码区别仅仅是把stack相关删去,然后换成ArrayList头插法
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> res = new ArrayList<ArrayList<Integer>>();
        if(pRoot == null)return res;
        ArrayList<TreeNode> queue = new ArrayList<TreeNode>();
        queue.add(pRoot);
        int layer = 1;
        while(!queue.isEmpty()){
            ArrayList<Integer> list = new ArrayList<Integer>();
            int size = queue.size();
            for(int i=0; i<=size-1; ++i){
                TreeNode node = queue.get(0);
                queue.remove(0);
                if(layer % 2 == 1){
                    list.add(node.val);
                }
                else{
                    list.add(0,node.val);//头插法,逆序 //【代码简洁,但效率比Stack低】
                }
                if(node.left != null)queue.add(node.left);
                if(node.right != null)queue.add(node.right);
            }
            res.add(list);
            ++layer;
        }
        return res;
    }
}//时间、空间都是 O(N)
View Code
复制代码

 

 


参考4

 

 

复制代码
public ArrayList<ArrayList<Integer>> Print(TreeNode pRoot) {
        ArrayList<ArrayList<Integer>> result = new ArrayList<>();
        if (pRoot == null) {
            return result;
        }
        // 创建一个队列
        Queue<TreeNode> queue = new LinkedList<>();
        // 根节点先入队
        queue.offer(pRoot);
        // 当队列不为空时
        while (!queue.isEmpty()) {

            int size = queue.size();
            ArrayList<Integer> list = new ArrayList<>();
            // 仅遍历当前层的元素,因为结果是按照层的维度存储的
            for (int i = 0; i < size; i ++) {
                // 弹出元素
                TreeNode node = queue.poll();
                list.add(node.val);
                // 如果左节点不为空,则入队
                if (node.left != null) {
                    queue.offer(node.left);
                }
                // 如果右节点不为空,则入队
                if (node.right != null) {
                    queue.offer(node.right);
                }
            }
            // 判断一下是否为奇数层,如果是,则将结果反着存储,
            // 这里将根节点那层设定为 第 0 层,为偶数层
            if (result.size() % 2 == 1) {
                Collections.reverse(list);
            }
            // 将结果以 层 为维度存储
            result.add(list);
        }
        return result;
    }
View Code
复制代码

 

 

 

 

posted @   yub4by  阅读(42)  评论(0编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
点击右上角即可分享
微信分享提示