测开面试算法题

1.Z 字形变换
将一个给定字符串 s 根据给定的行数 numRows ,以从上往下、从左到右进行 Z 字形排列。

输入:s = “PAYPALISHIRING”, numRows = 4
输出:“PINALSIGYAHRPI”
解释:
P I N
A L S I G
Y A H R
P I

思路:先确定有几行数据,存储数据先递增再递减

package com.exerice;

import java.util.ArrayList;
import java.util.List;

//Z字形变化
public class ZTest {
    public static void main(String[] args) {
        String s="LEETCOD";
        System.out.println(convert(s,3));
    }

    public static String convert(String s, int numRows) {
        if(numRows <2){ return s;}
        List<StringBuilder> result = new ArrayList<>();
        for(int i=0;i<numRows;i++){
            result.add(new StringBuilder());
        }
        int m=0,flag=-1;
        for(int i =0;i<s.length();i++){
            result.get(m).append(s.charAt(i));
            if(m==0 || m==numRows-1){flag=-flag;}
            m+=flag;
        }
        StringBuilder resultAll = new StringBuilder();
        for(int i=0;i<result.size();i++){
            resultAll.append(result.get(i));
        }
        return resultAll.toString();
    }
}

2.字符串转换整数 (atoi)

import java.util.regex.Matcher;
import java.util.regex.Pattern;
class Solution {
    public int myAtoi(String s) {
       int result=0;
        String regex="^[\\+\\-]?\\d+";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(s.trim());
        if (m.find()){
            try{
            result=Integer.parseInt(m.group());
            }catch (Exception e){
                result = s.trim().charAt(0) == '-' ? Integer.MIN_VALUE: Integer.MAX_VALUE;
            }
        }
        return result;

    }
}

3.盛最多水的容器
https://leetcode-cn.com/problems/container-with-most-water/

class Solution {
    public int maxArea(int[] height) {
    int i=0,j=height.length-1;
        int max=0;
        while(i<j){
            if(height[i]<height[j]){
                max=Math.max(max,(j-i)*height[i++]);
            }else{
                max=Math.max(max,(j-i)*height[j--]);
            }

        }
        return max;
    }
}

4.整数转罗马数字

class Solution {
    public String intToRoman(int num) {
        String[] ge={"","I","II","III","IV","V","VI","VII","VIII","IX"};
        String[] shi={"","X","XX","XXX","XL","L", "LX", "LXX", "LXXX", "XC"};
        String[] bai={"","C","CC","CCC","CD","D","DC", "DCC", "DCCC", "CM"};
        String[] qian={"","M","MM","MMM"};
        StringBuilder result=new StringBuilder();
        result.append(qian[num/1000]).append(bai[num%1000/100]).append(shi[num%100/10]).append(ge[num%10]);
        return result.toString();
    }
}

5.罗马数字转整数

class Solution {
    public int romanToInt(String s) {
        Map<Character, Integer> symbolValues = new HashMap<Character, Integer>() {{
        put('I', 1);
        put('V', 5);
        put('X', 10);
        put('L', 50);
        put('C', 100);
        put('D', 500);
        put('M', 1000);
    }};
    int result=0;
    for(int i=0;i<s.length();i++){
        char value=s.charAt(i);
        if(i<s.length()-1 && symbolValues.get(value)<symbolValues.get(s.charAt(i+1))){
            result+=-symbolValues.get(value);
        }else{
            result+=symbolValues.get(value);
        }

    }
    return result;
    }
}

6.最长公共前缀
输入:strs = [“flower”,“flow”,“flight”]
输出:“fl”

package com.exerice;

public class LongestPubString {
    public static void main(String[] args) {
        String[] strings={"aabbcc","aabb","aabcdef"};
        System.out.println(pub(strings));

    }
    

    public static String pub(String[] strings){
        String ret =strings[0];
        for(int i=1;i<strings.length;i++){
            while (!strings[i].startsWith(ret)){
                ret=ret.substring(0,ret.length()-1);
                if(ret.length() == 0){
                    return "";
                }
            }
        }
        return ret;
    }
}

7.最接近的三数之和
输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。

class Solution {
    public int threeSumClosest(int[] nums, int target) {
        int jishu= nums[0]+nums[1]+nums[2];
        Arrays.sort(nums);
        for(int i=0;i<nums.length-2;i++){
            if(i >0 &&nums[i]==nums[i-1]) continue;
            int j = i+1, k = nums.length - 1;
            while (j<k){
                int sum =nums[i]+nums[j]+nums[k];
                if(Math.abs(target-sum)<Math.abs(target-jishu)){
                    jishu=sum;
                }
                if(sum>target){
                    k--;
                }else if(sum < target){
                    j++;
                }else {
                    return jishu;
                }
            }
        }
        return jishu;

    }
}

8.电话号码的字母组合
输入:digits = “23”
输出:[“ad”,“ae”,“af”,“bd”,“be”,“bf”,“cd”,“ce”,“cf”]

package com.exerice;

import java.util.*;

//电话号码的字母组合,用队列解决
public class letterCombinations {
    public static void main(String[] args) {
        String digits="23";
        System.out.println(letterCombinations(digits));
    }
    public static List<String> letterCombinations(String digits) {
        if(digits == null || digits.length() ==0){
            return new ArrayList<>();
        }
       String[] phone ={"abc","def","ghi","jkl","mno","pqrs","tuv","wxyz"};
        Queue<String> stringQueue =new LinkedList<>();
        stringQueue.offer("");
        for(int i=0;i<digits.length();i++){
            int len1=stringQueue.size();
            for(int j=0;j<len1;j++){
                String tmp = stringQueue.poll();
                System.out.println("tmp:"+tmp);
                int m =digits.charAt(i)-48-2;
                for(char letter:phone[m].toCharArray()){
                    stringQueue.offer(tmp+letter);
                    System.out.println(""+tmp+letter);
                }
            }
        }
        return (List<String>) stringQueue;
    }
}

9.连续最长子序列

package com.exerice;

//最长递增子序列
//输入:nums = [10,9,2,5,3,7,101,18]
//解释:最长递增子序列是 [2,3,7,101],因此长度为 4
public class IncreasingsTest {
    public static void main(String[] args) {
        int[] arr = {10, 9, 2, 5, 3, 7, 101, 1};
        System.out.println(length(arr));

    }

    public static int length(int[] arr) {
        int len = arr.length;
        int[] num = new int[len];
        num[0] = 1;
        int max = 1;
        for (int i = 1; i < len; i++) {
            num[i] = 1;
            for (int j = 0; j < i; j++) {
                if (arr[j] < arr[i]) {
                    num[i] = Math.max(num[i], num[j] + 1);
                }
            }
            max = Math.max(max, num[i]);

        }

        return max;

    }
}

10.括号生成
输入:n = 3
输出:["((()))","(()())","(())()","()(())","()()()"]

package com.exerice;

import java.util.ArrayList;
import java.util.List;


//括号生成,输入:n = 3
//输出:["((()))","(()())","(())()","()(())","()()()"]
// 解题思路
//     1. 将问题抽象成树形结构遍历问题
//      2.判断是是否是有效括号
public class KuoHaoNewTest {
    public static void main(String[] args) {
        int n =3;
        System.out.println(generateParenthesis(3));
    }
    public static List<String> generateParenthesis(int n) {
        List<String> res = new ArrayList<>();
        List<String> result = new ArrayList<>();
        if(n<=0){return res;}
        dnf(n,"",res);
        for(String key:res){
            if(isvalid(key)){
                result.add(key);
            }

        }
        return result;

    }
    public static void dnf(int n,String path,List<String> res){
        if(path.length() == 2*n){
            res.add(path);
            return;
        }
        dnf(n,path+"(",res);
        dnf(n,path+")",res);

    }

    //https://leetcode-cn.com/problems/generate-parentheses/solution/pei-yang-chou-xiang-si-wei-hui-su-jie-fa-7dwu/

    //判断是否是有效括号
    public static boolean isvalid(String str){
        while (str.contains("()")){
            str=str.replaceAll("\\(\\)","");
        }
        return str.length()==0;
    }

}

11.全排列


import java.util.ArrayList;
import java.util.List;

public class AllZuHeTest {
    public static void main(String[] args) {
        int[] arr = {1, 2};
        System.out.println(all(arr));

    }
    public static List<List<Integer>> all(int[] arr) {
        List<List<Integer>> lists = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        dfs(arr, -1, path, lists);
        return lists;
    }

    public static void dfs(int[] nums, int index, List<Integer> path, List<List<Integer>> lists) {
        if(path.size() == nums.length){
            lists.add(new ArrayList<>(path));
            return;
        }
        for(int i=0;i<nums.length;i++){
            if(path.contains(nums[i])){continue;}
            path.add(nums[i]);
            dfs(nums,i,path,lists);
            path.remove(path.size()-1);
        }
    }
}

12.全排列 II
给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。
输入:nums = [1,1,2]
输出:
[[1,1,2],
[1,2,1],
[2,1,1]]

package com.exerice;

import java.util.ArrayList;
import java.util.List;

public class AllZuHeTest2 {
    public static void main(String[] args) {
        int[] arr = {1,1,2};
        System.out.println(all(arr));

    }
    public static List<List<Integer>> all(int[] arr) {
        List<List<Integer>> lists = new ArrayList<>();
        List<Integer> path = new ArrayList<>();
        boolean[] used= new boolean[arr.length];
        dfs(arr, -1, path, lists,used);
        return lists;
    }

    public static void dfs(int[] nums, int index, List<Integer> path, List<List<Integer>> lists,boolean[] used) {
        if(path.size() == nums.length){
            lists.add(new ArrayList<>(path));
            return;
        }
        for(int i=0;i<nums.length;i++){
            if(used[i]){continue;}
            if(i>0 &&nums[i]== nums[i-1] && used[i-1]){continue;}
            path.add(nums[i]);
            used[i] = true;
            dfs(nums,i,path,lists,used);
            used[i] = false;
            path.remove(path.size()-1);
        }
    }
}

13.链表两两交换

package com.exerice;

//两两交换链表中的节点
//如果链表中至少有两个节点,则在两两交换链表中的节点之后
// ,原始链表的头节点变成新的链表的第二个节点,原始链表的第二个节点变成新的链表的头节点。
// 链表中的其余节点的两两交换可以递归地实现。在对链表中的其余节点递归地两两交换之后,更新节点之间的指针关系
// ,即可完成整个链表的两两交换。

public class ListNodeTranfer {
    public ListNode swapPairs(ListNode head) {
        if(head == null || head.next == null){
            return head;
        }
        ListNode NewHead = head.next;
        head.next=swapPairs(NewHead.next);
        NewHead.next=head;
        return NewHead;

    }
}

14.链表反转

package com.testfan.ll;


//链表反转
public class ListNodeTest2 {
    public ListNode test3(ListNode head) {
        ListNode result = null;
        ListNode cur = head;
        while (cur != null) {
            ListNode node = cur.next;
            cur.next = result;
            result = cur;
            cur = node;
        }
        return result;

    }
}

14.有N个手机,编号为1-N,点开一次开灯再点一次关灯。第一次开所有点灯,第二次开编号为2的倍数的灯,第三次开编号为3的倍数的灯,。。。。m次

package com.testfan.ll;

import java.util.HashMap;

//思路:定义一个map,key存放灯的编号,value存放点了几次。点一次加1,奇数的就是亮的灯
public class KaiDenTest {
    public static void main(String[] args) {
        System.out.println(light(5,3));

    }
    public static int light(int n,int m){
        int liangDengNUm =0;
        HashMap<Integer,Integer> resultMap = new HashMap<>();
        for(int i=1;i<n+1;i++){
            resultMap.put(i,1);
        }
        for(int i:resultMap.keySet()){
            for(int j=2;j<m+1;j++){
                if(i%j==0 ){
                    int value = resultMap.get(i)+1;
                    resultMap.put(i,value);
                }
            }
        }
        for(Integer value:resultMap.values()){
            if(!(value%2 ==0)){
                liangDengNUm+=1;
            }

        }

        return liangDengNUm;

    }

}

15.股票收益最大

package exercise;
/*
*股票收益最大
* 有一道算法题,很有意思:给你一个数组,代表每天股票的买/卖价序列,要求在序列期间内最多只允许买、卖各一次(先买后卖,买要在卖之前),
* 求此期间内的最大收益是多少(可以选择不卖,即收益为0)
 */


public class ArrayTest {
    public static void main(String[] args) {
        int[] arr ={7,1,5,3,6,4};
        System.out.println("股票最大收益:"+mostIncome2(arr));
    }
    public static int mostIncome(int[] arr){
        int max =0;
        for(int i=0;i<arr.length;i++){
            for(int j=i+1;j<arr.length-1;j++){
                if(arr[i]< arr[j] && arr[j]- arr[i] >max){
                   max = arr[j]- arr[i];
                }
            }
        }
        return max;
    }
    //第二种思路:动态规划
    //遍历到第一天的时候,我们记住价格,遍历到第二天的时候,我们可以得到前两天的最小值,遍历到第三天的时候,
    // 我们可以得到前三天的最小值……当我们遍历到N天的时候,我们可以得到前N天的最小值,然后和N+1天的价格相比,
    // 如果N+1天的价格小于等于前N天的最小值,那么肯定是不能卖的,那么就刷新最小值!如果N+1天的价格大于前N天的最小值
    // ,那么就计算前N天的最小值与N+1天的价格的差,也就是盈利差,并随时记录下来!
    public static int mostIncome2(int[] arr){
        int minValue = arr[0];
        int max =0;
        for(int i=1;i<arr.length;i++){
            if(arr[i] >minValue){
                max=Math.max(max,arr[i]-minValue);
            }else {
                minValue=arr[i];
            }
        }
        return max;
    }

}

16.n!的阶乘有多少个0

package exercise;
/*
*n!的阶乘有多少个0,主要看有多少个5
 */
public class NTest {
    public static void main(String[] args) {
        int num =10000;
        System.out.println(test(num));
    }
    public static int test(int num){
        int result=0;
        int tmp =5;
        while (tmp <= num){
            result=result+num/tmp;
            tmp=tmp*5;
        }

        return result;

    }
}

  1. 数字转字符串
package exercise;

/*
* 数字转字符串
* */
public class IntTurnString {
    public static void main(String[] args) {
        int s = 333322;
        System.out.println(turn(s));
    }
    public static String turn(int num){
        StringBuilder result= new StringBuilder();
        while (num !=0){
            result.append(num%10);
            num=num/10;
        }

        return  result.reverse().toString();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值