牛客网面试高频题top100(51~60)

本文分享了51-60道Java实现的面试高频算法题目,涉及链表判断回文、编辑距离、二叉树路径和、路径和等于特定值、区间反转、路径数量、合并区间、最长公共子序列、中位数查找、搜索及完全二叉树判断。适合准备面试者提升算法实战能力。
摘要由CSDN通过智能技术生成

面试高频算法题top100(51~60)java实现

51.判断一个链表是否为回文结构

给定一个链表,请判断该链表是否为回文结构。
( 回文是指该字符串正序逆序完全一致。 )

import java.util.*;
public class Solution {
    public boolean isPail (ListNode head) {
        ListNode temp = head;
        int len = 0;
        Stack<Integer> stack = new Stack<>();
        while(temp!=null){
            len +=1;
            stack.push(temp.val);
            temp = temp.next;
        }
        len /= 2;
        while(len-->0){
            if(head.val!=stack.pop())
                return false;
            head = head.next;
        }
        return true;
    }
}

52.编辑距离(二)

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

import java.util.*;


public class Solution {
    public int minEditCost (String str1, String str2, int ic, int dc, int rc) {
        int m = str1.length();
        int n = str2.length();
        int[][] dp = new int[m+1][n+1];
        for(int i=1;i<=m;i++)
            dp[i][0] = i*dc;
        for(int j=1;j<=n;j++)
            dp[0][j] = j*ic;
        for(int i=1;i<=m;i++){
            for(int j=1;j<=n;j++){
                if(str1.charAt(i-1)==str2.charAt(j-1))
                    dp[i][j] = dp[i-1][j-1];
                else{
                    dp[i][j] = Math.min(dp[i-1][j-1]+rc,Math.min(dp[i][j-1]+ic,dp[i-1][j]+dc));
                }
            }
        }
        return dp[m][n];
    }
}

空间优化为O(n):

import java.util.*;


public class Solution {
    
    public int minEditCost (String str1, String str2, int ic, int dc, int rc) {
        int m = str1.length();
        int n = str2.length();
        int[] dp = new int[n+1];
        for(int j=1;j<=n;j++)
            dp[j] = j*ic;
        for(int i=1;i<=m;i++){
            int pre = dp[0];
            dp[0] = i*dc;
            for(int j=1;j<=n;++j){
                int temp = dp[j];
                if(str1.charAt(i-1)==str2.charAt(j-1)) dp[j] = pre;
                else{
                    dp[j] = Math.min(pre+rc,Math.min(dp[j-1]+ic,temp+dc));
                }
                pre = temp;
            }
        }
        return dp[n];
}
}

53.二叉树根节点到叶子节点的所有路径和

给定一个二叉树的根节点root,该树的节点值都在数字 0−9\ 0-9 0−9 之间,每一条从根节点到叶子节点的路径都可以用一个数字表示。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
在这里插入图片描述
在这里插入图片描述

import java.util.*;

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

public class Solution {
  
    public int sumNumbers (TreeNode root) {
        int sum = 0;
        Stack<TreeNode> Node = new Stack<>();
        Stack<Integer> num = new Stack<>();
        if(root==null) return 0;
        Node.push(root);
        num.push(root.val);
        while(!Node.empty()){
            TreeNode temp = Node.pop();
            int t = num.pop();
            if(temp.left==null && temp.right==null)
                sum += t;
            else{
                if(temp.left!=null){
                    Node.push(temp.left);
                    num.push(t*10 + temp.left.val);
                }
                if(temp.right!=null){
                    Node.push(temp.right);
                    num.push(t*10 + temp.right.val);
                }
            }
        }
        return sum;
    }
}

54.二叉树中和为某一值的路径(二)

输入一颗二叉树的根节点root和一个整数expectNumber,找出二叉树中结点值的和为expectNumber的所有路径。
1.该题路径定义为从树的根结点开始往下一直到叶子结点所经过的结点
2.叶子节点是指没有子节点的节点
3.路径只能从父节点到子节点,不能从子节点到父节点
4.总节点数目为n
在这里插入图片描述

import java.util.ArrayList;
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

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

    }

}
*/
public class Solution {
    ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int expectNumber) {
        search(root,expectNumber,new ArrayList<>());
        return res;
    }
    public void search(TreeNode root,int tar,ArrayList<Integer> list){
        if(root==null) return;
        tar -= root.val;
        list.add(root.val);
        if(tar==0 && root.left==null && root.right==null)
            res.add(new ArrayList(list));
        search(root.left,tar,list);
        search(root.right,tar,list);
        list.remove(list.size()-1);
        tar += root.val;
    }
}

55.链表内指定区间反转

在这里插入图片描述

import java.util.*;

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

public class Solution {
    
    public ListNode reverseBetween (ListNode head, int m, int n) {
        ListNode pre = new ListNode(-1);
        pre.next = head;
        ListNode dummy = pre;
        int count = 0;
        for(int i=1;i<m;i++) {
            pre = head;
            head = head.next;
        }
        ListNode start = head;
        for(int i=m;i<n;i++){
            head = head.next;
        }
        ListNode next = head.next;
        head.next = null;
        pre.next = reverse(start);
        start.next =next;
        return dummy.next; 
    }
    public ListNode reverse(ListNode h1){
        ListNode pre = null;
        ListNode cur = null;
        while(h1!=null){
            cur = h1.next;
            h1.next = pre;
            pre = h1;
            h1 = cur;
        }
        return pre;
    }
}

56.不同路径的数目(一)

在这里插入图片描述

import java.util.*;


public class Solution {
  
    public int uniquePaths (int m, int n) {
        int[][] dp = new int[m][n];
        for(int i=0;i<m;i++)
            dp[i][0] = 1;
        for(int j=0;j<n;j++)
            dp[0][j] = 1;
        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                dp[i][j] = dp[i][j-1] + dp[i-1][j];
            }
        }
        return dp[m-1][n-1];
    }
}

空间复杂度优化为O(m+n):

import java.util.*;
public class Solution {
    public int uniquePaths (int m, int n) {
        //矩阵只要有一条边为1,路径数就只有一种了
        if(m == 1 || n == 1) 
            return 1;
        //两个分支
        return uniquePaths(m - 1, n) + uniquePaths(m, n - 1); 
    }
}

空间复杂度优化为O(1)且时间复杂度优化为O(n):

import java.util.*;
public class Solution {
    public int uniquePaths (int m, int n) {
        //防止溢出
        long res = 1; 
        for(int i = 1; i < n; i++)
            //根据公式计算
            res = res * (m + i - 1) / i; 
        return (int)res;
    }
}

57.合并区间

给出一组区间,请合并所有重叠的区间。请保证合并后的区间按区间起点升序排列。
在这里插入图片描述

import java.util.*;
/**
 * Definition for an interval.
 * public class Interval {
 *     int start;
 *     int end;
 *     Interval() { start = 0; end = 0; }
 *     Interval(int s, int e) { start = s; end = e; }
 * }
 */
public class Solution {
    public ArrayList<Interval> merge(ArrayList<Interval> intervals) {
        Collections.sort(intervals,new Comparator<Interval>(){
            @Override
            public int compare(Interval o1,Interval o2){
                return o1.start-o2.start;
            }
        });
        ArrayList<Interval> res = new ArrayList<>();
        for(int i=0;i<intervals.size();i++){
            if(i==0 || intervals.get(i).start>res.get(res.size()-1).end){
                res.add(intervals.get(i));
            }else{
                res.get(res.size()-1).end = Math.max(res.get(res.size()-1).end,intervals.get(i).end);
            }
        }
        return res;
    }
}

58.最长公共子序列(二)

给定两个字符串str1和str2,输出两个字符串的最长公共子序列。如果最长公共子序列为空,则返回"-1"。目前给出的数据,仅仅会存在一个最长的公共子序列
在这里插入图片描述

import java.util.*;


public class Solution {
    /**
     * longest common subsequence
     * @param s1 string字符串 the string
     * @param s2 string字符串 the string
     * @return string字符串
     */
    public String LCS (String s1, String s2) {
        int len1 = s1.length(),len2 = s2.length();
        int[][] dp = new int[len1+1][len2+1];
        if(len1==0 || len2==0) return "-1";
        for(int i=1;i<=len1;i++){
            for(int j=1;j<=len2;j++){
                if(s1.charAt(i-1)==s2.charAt(j-1))
                    dp[i][j] = dp[i-1][j-1] + 1;
                else
                    dp[i][j] = Math.max(dp[i-1][j],dp[i][j-1]);
            }
        }
        if(dp[len1][len2]==0) return "-1";
        StringBuilder str = new StringBuilder();
        while(len1>0 && len2>0){
            if(s1.charAt(len1-1)==s2.charAt(len2-1)){
                str.append(s1.charAt(len1-1));
                len2--;
                len1--;
            } 
            else if(dp[len1][len2-1]>dp[len1-1][len2])
                len2--;
            else
                len1--;
                
        }
        return str.reverse().toString();
    }
}

59.在两个长度相等的排序数组中找到中位数

给定两个递增数组arr1和arr2,已知两个数组的长度都为N,求两个数组中所有数的上中位数。
上中位数:假设递增序列长度为n,为第n/2个数 。
在这里插入图片描述

import java.util.*;


public class Solution {
  
    public int findMedianinTwoSortedAray (int[] arr1, int[] arr2) {
        int left1=0,right1 = arr1.length-1,left2=0,right2 = arr2.length-1;
        while(left1<right1){
            int mid1 = left1 + (right1-left1)/2;
            int mid2 = left2 + (right2-left2)/2;
            int temp = (right1-left1+1)%2==0?1:0;
            if(arr1[mid1]==arr2[mid2])
                return arr1[mid1];
            else if(arr1[mid1]<arr2[mid2]){
                left1 = mid1+temp;
                right2 = mid2;
            }else{
                right1 = mid1;
                left2 = mid2+temp;
            }
        }
        return Math.min(arr1[left1],arr2[left2]);
    }
}

60.判断一棵二叉树是否为搜索二叉树和完全二叉树

给定一棵二叉树,已知其中的节点没有重复值,请判断该二叉树是否为搜索二叉树和完全二叉树。
在这里插入图片描述

import java.util.*;

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

public class Solution {
    
    public boolean[] judgeIt (TreeNode root) {
        boolean[] res = new boolean[2];
        res[0] = Is_search(root);
        res[1] = Is_comple(root);
        return res;
    }
    public boolean Is_search(TreeNode root){
        ArrayList<Integer> list = new ArrayList<>();
       search(root,list);
        int pre = Integer.MIN_VALUE;
        for(int i:list){
            if(i>pre)
                pre = i;
            else
                return false;
        }
        return true;
    }
    public void search(TreeNode root,ArrayList<Integer> list){
        if(root==null) return;
        search(root.left,list);
        list.add(root.val);
        search(root.right,list);
    }
    public boolean Is_comple(TreeNode root){
        if(root==null) return true;
        boolean flag = false;
        Queue<TreeNode> que = new LinkedList<>();
        que.add(root);
        while(!que.isEmpty()){
            TreeNode temp = que.poll();
            if(flag==true){
                if(temp.left!=null || temp.right!=null)
                    return false;
            }
            if(temp.left==null && temp.right!=null)
                return false;
            if(temp.left==null || temp.right==null)
                flag = true;
            if(temp.left!=null)
                que.add(temp.left);
            if(temp.right!=null)
                que.add(temp.right);
        }
        return true;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值