程序员面试过程中常见的手撕代码题

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/hywel_xue/article/details/82426100

最长上升子序列(LIS)长度

方法一、动态规划方法 时间复杂度为O(n2)

public class Solution {
    public int lis(int[] nums) {
        if(nums.length==0){
            return 0;
        }
        int dp[]=new int[nums.length];
        for(int i=0;i<nums.length;i++){
            dp[i]=1;
            for(int j=0;j<i;j++){
                if(nums[i]>nums[j]&&dp[j]+1>dp[i])
                    dp[i]=dp[j]+1;
            }
        }
        int max=Integer.MIN_VALUE;
        for(int i=0;i<nums.length;i++){
            max=Math.max(max, dp[i]);
        }
        return max;
    }
}

方法二、时间复杂度为O(nlog(n))

import java.util.*;
public class Main {
    static int[] arr;
    static int[] ans;
    static int index;   

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        arr = new int[n];
        ans = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = sc.nextInt();
        }
        ans[0] = arr[0];
        index = 0;
        for(int i = 1; i < n; i++){
            if(arr[i] > ans[index]){
                ans[++index] = arr[i];
            } else {
                int pos = binary_search(i);
                ans[pos] = arr[i];
            }
        }
        System.out.println(index + 1);
    }

    public static int binary_search(int i){
        int left = 0, right = index, mid;
        while(left < right){
            mid = left + (right - left) / 2;
            if(ans[mid] == arr[i]){
                return mid;
            } else if(ans[mid] > arr[i]){
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }
}

详细方案参考: 最长上升子序列(LIS)长度的O(nlogn)算法

最长公共子序列(LCS) 动态规划解法

import java.util.*;
import java.lang.*;
public class Solution {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        String x = sc.next();
        String y = sc.next();
        getLCS(x,y);
    }   
    public static void getLCS(String x, String y){
        char[] s1 = x.toCharArray();
        char[] s2 = y.toCharArray();
        //此处的棋盘长度要比字符串长度多加1,需要多存储一行0和一列0
        int[][] array = new int[x.length()+1][y.length()+1];

        for(int j = 0; j < array[0].length; j++){//第0行第j列全部赋值为0
            array[0][j] = 0;
        }
        for(int i = 0; i < array.length; i++){//第i行,第0列全部为0
            array[i][0] = 0;
        }

        for(int m = 1; m < array.length; m++){//利用动态规划将数组赋满值
            for(int n = 1; n < array[m].length; n++){
                if(s1[m - 1] == s2[n - 1]){
                    array[m][n] = array[m-1][n-1] + 1;//动态规划公式一
                }else{
                    array[m][n] = Math.max(array[m -1][n], array[m][n -1]);//动态规划公式二
                }
            }
        }
        Stack<Character> stack = new Stack<>();
        int i = x.length() - 1;
        int j = y.length() - 1;

        while((i >= 0) && (j >= 0)){
            if(s1[i] == s2[j]){//字符串从后开始遍历,如若相等,则存入栈中
                stack.push(s1[i]);
                i--;
                j--;
            }else{
                //如果字符串的字符不同,则在数组中找相同的字符
                //注意:数组的行列要比字符串中字符的个数大1,因此i和j要各加1
                if(array[i+1][j] > array[i][j+1]){
                    j--;
                }else{
                    i--;
                }
            }
        }

        while(!stack.isEmpty()){//打印输出栈正好是正向输出最大的公共子序列
            System.out.print(stack.pop());
        }           
    }
}

详细方案参考: Java-LCS最长公共子序列(动态规划实现)
求解两个字符串的最长公共子序列

展开阅读全文

没有更多推荐了,返回首页