刷题打卡第四天

2022-11-20

牛客-面试高频榜单

2 简单 3 中等 1困难

19 连续子数组的最大和

输入一个长度为n的整型数组array,数组中的一个或连续多个整数组成一个子数组,子数组最小长度为1。求所有子数组的和的最大值。

import java.util.*;
public class Solution {
    public int FindGreatestSumOfSubArray(int[] array) {
        //记录到下标i为止的最大连续子数组和
        int[] dp = new int[array.length]; 
        dp[0] = array[0];
        int maxsum = dp[0];
        for(int i = 1; i < array.length; i++){
            //状态转移:连续子数组和最大值
            dp[i] = Math.max(dp[i - 1] + array[i], array[i]); 
            //维护最大值
            maxsum = Math.max(maxsum, dp[i]); 
        }
        return maxsum;
    }
}

4判断链表中是否有环

public class Solution {
    public boolean hasCycle(ListNode head) {
        //先判断链表为空的情况
        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; 
    }
}

40 链表相加(二)

假设链表中每一个节点的值都在 0 - 9 之间,那么链表整体就可以代表一个整数。

给定两个这种链表,请生成代表两个整数相加值的结果链表。

数据范围:0≤n,m≤1000000,链表任意值0≤val≤9
要求:空间复杂度 O*(n),时间复杂度 O*(n)

import java.util.*;
public class Solution {
    //反转链表
    public ListNode ReverseList(ListNode pHead) { 
        if(pHead == null)
            return null;
        ListNode cur = pHead;
        ListNode pre = null;
        while(cur != null){
            //断开链表,要记录后续一个
            ListNode temp = cur.next;
            //当前的next指向前一个
            cur.next = pre; 
            //前一个更新为当前
            pre = cur; 
            //当前更新为刚刚记录的后一个
            cur = temp; 
        }
        return pre;
    }
    
    public ListNode addInList (ListNode head1, ListNode head2) {
        //任意一个链表为空,返回另一个
        if(head1 == null) 
            return head2;
        if(head2 == null)
            return head1;
        //反转两个链表
        head1 = ReverseList(head1); 
        head2 = ReverseList(head2);
        //添加表头
        ListNode res = new ListNode(-1); 
        ListNode head = res;
        //进位符号
        int carry = 0; 
        //只要某个链表还有或者进位还有
        while(head1 != null || head2 != null || carry != 0){ 
            //链表不为空则取其值
            int val1 = head1 == null ? 0 : head1.val; 
            int val2 = head2 == null ? 0 : head2.val;
            //相加
            int temp = val1 + val2 + carry; 
            //获取进位
            carry = temp / 10; 
            temp %= 10; 
            //添加元素
            head.next = new ListNode(temp); 
            head = head.next;
            //移动下一个
            if(head1 != null) 
                head1 = head1.next;
            if(head2 != null)
                head2 = head2.next;
        }
        //结果反转回来
        return ReverseList(res.next); 
    }
}

127 最长公共子串

给定两个字符串str1和str2,输出两个字符串的最长公共子串

题目保证str1和str2的最长公共子串存在且唯一。

import java.util.*;
public class Solution {
    public String LCS (String str1, String str2) {
        //dp[i][j]表示到str1第i个个到str2第j个为止的公共子串长度
        int[][] dp = new int[str1.length() + 1][str2.length() + 1]; 
        int max = 0;
        int pos = 0;
        for(int i = 1; i <= str1.length(); i++){
            for(int j = 1; j <= str2.length(); j++){
                //如果该两位相同
                if(str1.charAt(i - 1) == str2.charAt(j - 1)) 
                    //则增加长度
                    dp[i][j] = dp[i - 1][j - 1] + 1; 
                else 
                    //该位置为0
                    dp[i][j] = 0; 
                //更新最大长度
                if(dp[i][j] > max){ 
                    max = dp[i][j];
                    pos = i - 1;
                }
            }
        }
        return str1.substring(pos - max + 1, pos + 1);
    }
}

14 按之字形顺序打印二叉树

给定一个二叉树,返回该二叉树的之字形层序遍历,(第一层从左向右,下一层从右向左,一直这样交替)

import java.util.*;
public class Solution {
    public ArrayList<ArrayList<Integer> > Print(TreeNode pRoot) {
        TreeNode head = pRoot;
        ArrayList<ArrayList<Integer> > res = new ArrayList<ArrayList<Integer>>();
        if(head == null)
            //如果是空,则直接返回空list
            return res; 
        //队列存储,进行层次遍历
        Queue<TreeNode> temp = new LinkedList<TreeNode>(); 
        temp.offer(head);
        TreeNode p;
        boolean flag = true;
        while(!temp.isEmpty()){
            //记录二叉树的某一行
            ArrayList<Integer> row = new ArrayList<Integer>();  
            int n = temp.size();
            //奇数行反转,偶数行不反转
            flag = !flag; 
            //因先进入的是根节点,故每层节点多少,队列大小就是多少
            for(int i = 0; i < n; i++){
                p = temp.poll();
                row.add(p.val);
                //若是左右孩子存在,则存入左右孩子作为下一个层次
                if(p.left != null)
                    temp.offer(p.left);
                if(p.right != null)
                    temp.offer(p.right);
            }
            //奇数行反转,偶数行不反转
            if(flag)  
                Collections.reverse(row);
            res.add(row);
        }
        return res;
    }
}

35 编辑距离(二)

给定两个字符串str1和str2,再给定三个整数ic,dc和rc,分别代表插入、删除和替换一个字符的代价,请输出将str1编辑成str2的最小代价。

import java.util.*;

public class Solution {
    /**
     * min edit cost
     * @param str1 string字符串 the string
     * @param str2 string字符串 the string
     * @param ic int整型 insert cost
     * @param dc int整型 delete cost
     * @param rc int整型 replace cost
     * @return int整型
     */
    public int minEditCost (String str1, String str2, int ic, int dc, int rc) {
        // write code here
        int n = str1.length(), m = str2.length();
        int[][] dp = new int[n+1][m+1];
        for(int i = 1; i <= n; i++){
           dp[i][0] = i*dc; 
        }
        for(int j = 1; j <= m; j++){
           dp[0][j] = j*ic;
        }
        for(int i = 1; i <= n; i++){
           for(int j = 1; j <= m; j++){
               if(str1.charAt(i-1) == str2.charAt(j-1))
                   dp[i][j] = dp[i-1][j-1];
               else
                   dp[i][j] = min(dp[i-1][j]+dc, dp[i][j-1]+ic, dp[i-1][j-1]+rc);
            }
        }
        return dp[n][m];
    }

    public int min(int a, int b, int c){
        return Math.min(a, Math.min(b, c));
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值