牛客网面试高频题top100(91~100)

面试高频算法题top100(91~100)java实现

91.验证IP地址

编写一个函数来验证输入的字符串是否是有效的 IPv4 或 IPv6 地址
在这里插入图片描述

import java.util.*;


public class Solution {
    public String solve (String IP) {
        if(Ipv4(IP))
            return "IPv4";
        else if(Ipv6(IP))
            return "IPv6";
        return "Neither";
    }
    public boolean Ipv4(String IP){
        String[] str = IP.split("\\.",-1);
        if(str.length!=4) return false;
        for(String st:str){
            if(st.length()==0) return false;
            try{
                int temp = Integer.parseInt(st,10);
                if(temp>255 || String.valueOf(temp).length()!= st.length())
                return false;
            }catch(NumberFormatException numberFormatException){
                return false;
            }
        }
        return true;
    }
    public boolean Ipv6(String IP){
        String[] str = IP.split(":",-1);
        
        if(str.length!=8) return false;
        for(String st:str){
            if(st.length()==0 || st.length()>4) return false;
            try{
                int temp = Integer.parseInt(st,16);
            }catch(NumberFormatException numberFormatException){
                return false;
            }
        }
        return true;
    }
}

92.大数乘法

以字符串的形式读入两个数字,编写一个函数计算它们的乘积,以字符串形式返回。
在这里插入图片描述

import java.util.*;


public class Solution {
    
    public String solve (String s, String t) {
        int n = s.length(),m = t.length();
        if(n==0 || m==0) return "";
        if(s.equals("0") || t.equals("0")) return "0";
        int[] num = new int[n+m];
        for(int i=n-1;i>=0;i--){
            for(int j=m-1;j>=0;j--){
                num[i+j+1] += ((s.charAt(i)-'0')*(t.charAt(j)-'0'));
            }
        }
        int more = 0;
        StringBuilder res = new StringBuilder();
        for(int i=num.length-1;i>=1;i--){
            more += num[i];
            res.append(more%10);
            more /= 10;
        }
        if(more>0) res.append(more);
        return res.reverse().toString();
    }
}

93.集合的所有子集(一)

现在有一个没有重复元素的整数集合S,求S的所有子集
注意:你给出的子集中的元素必须按升序排列,给出的解集中不能出现重复的元素
在这里插入图片描述

import java.util.*;

public class Solution {
    ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> subsets(int[] S) {
        for(int i=0;i<=S.length;i++)
            search(S,i,0,new ArrayList<>());
        return res;
    }
    public void search(int[] S,int len,int index,ArrayList<Integer> list){
        if(len==0){
            res.add(new ArrayList<>(list));
            return;
        }
        for(int i=index;i<S.length;i++){
            list.add(S[i]);
            search(S,len-1,i+1,list);
            list.remove(list.size()-1);
        }
    }
}

94.没有重复项数字的全排列

给出一组数字,返回该组数字的所有排列 (以数字在数组中的位置靠前为优先级,按字典序排列输出。)
在这里插入图片描述

import java.util.*;

public class Solution {
    ArrayList<ArrayList<Integer>> res = new ArrayList<>();
    public ArrayList<ArrayList<Integer>> permute(int[] num) {
        Allsort(num,new ArrayList<>());
        return res;
    }
    public void Allsort(int[] num,ArrayList<Integer> list){
        if(list.size()==num.length){
            res.add(new ArrayList<>(list));
            return;
        }
        for(int i=0;i<num.length;i++){
            if(list.contains(num[i]))
               continue;
            list.add(num[i]);
            Allsort(num,list);
            list.remove(list.size()-1);
        }
    }
}

95.链表中倒数最后K个结点

输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。
如果该链表长度小于k,请返回一个长度为 0 的链表。
在这里插入图片描述

import java.util.*;

/*
 * public class ListNode {
 *   int val;
 *   ListNode next = null;
 *   public ListNode(int val) {
 *     this.val = val;
 *   }
 * }
 */

public class Solution {
    public ListNode FindKthToTail (ListNode pHead, int k) {
        ListNode dummy = pHead;
        int count = 0;
        while(pHead!=null){
            count ++;
            pHead = pHead.next;
        }
        pHead = dummy;
        if(count<k)  return null;
        int j=0;
        while(j!=count-k){
            pHead = pHead.next;
            j++;
        }
        return pHead;
    }
}

96.兑换零钱

给定数组arr,arr中所有的值都为正整数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个aim,代表要找的钱数,求组成aim的最少货币数。
如果无解,请返回-1.
在这里插入图片描述在这里插入图片描述

import java.util.*;


public class Solution {
    
    public int minMoney (int[] arr, int aim) {
        if(aim==0) return 0;
        if(arr.length==0) return -1;
        int[] dp = new int[aim+1];
        for(int i=1;i<=aim;i++)
            dp[i] = aim;
        for(int i=1;i<=aim;i++){
            for(int j:arr){
                if(i>=j)
                    dp[i] = Math.min(dp[i],dp[i-j]+1);
            }
        }
        return dp[aim]==aim?-1:dp[aim];
    }
}

97.寻找峰值

给定一个长度为n的数组nums,请你找到峰值并返回其索引。数组可能包含多个峰值,在这种情况下,返回任何一个所在位置即可。
1.峰值元素是指其值严格大于左右相邻值的元素。严格大于即不能有等于
2.假设 nums[-1] = nums[n] = −∞-\infty−∞
3.对于所有有效的 i 都有 nums[i] != nums[i + 1]
在这里插入图片描述

import java.util.*;


public class Solution {
    
    public int findPeakElement (int[] nums) {
        int left = 0;
        int right = nums.length-1;
        if(nums.length==1) return 0;
        if(nums[0]>nums[1])  return 0;
        if(nums[right]>nums[right-1]) return right;
        int mid = 0;
        while(left<=right){
             mid = left + (right-left)/2;
            if(nums[mid]>nums[mid-1] && nums[mid]>nums[mid+1])
                break;
            if(nums[mid]<nums[mid-1])
                right = mid;
            else if(nums[mid]<nums[mid+1])
                left = mid;
                
        }
        return mid;
    }
}

98.最小覆盖子串

给出两个字符串 s 和 t,要求在 s 中找出最短的包含 t 中所有字符的连续子串。
在这里插入图片描述

import java.util.*;
public class Solution {
    //检查是否有小于0的
    boolean check(int[] hash) { 
        for (int i = 0; i < hash.length; i++) {
            if (hash[i] < 0)
                return false;
        }
        return true;
    };
    
    public String minWindow (String S, String T) {
        int cnt = S.length() + 1;
        //记录目标字符串T的字符个数
        int[] hash = new int[128]; 
        for(int i = 0; i < T.length(); i++)
        //初始化哈希表都为负数,找的时候再加为正
            hash[T.charAt(i)] -= 1; 
        int slow = 0, fast = 0;  
        //记录左右区间
        int left = -1, right = -1;  
        for(; fast < S.length(); fast++){
            char c = S.charAt(fast);
            //目标字符匹配+1
            hash[c]++;
            //没有小于0的说明都覆盖了,缩小窗口
            while(check(hash)){  
                //取最优解
                if(cnt > fast - slow + 1){ 
                    cnt = fast - slow + 1;  
                    left = slow;
                    right = fast;
                }
                c = S.charAt(slow);
                //缩小窗口的时候减1
                hash[c]--; 
                //窗口缩小
                slow++;      
            }
        }
        //找不到的情况
        if(left == -1)     
            return "";
        return S.substring(left, right + 1);
    }
}

99.二维数组中的查找

在一个二维数组array中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序。请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数。
在这里插入图片描述


public class Solution {
    public boolean Find(int target, int [][] array) {
        if(array.length==0 || array[0].length==0) return false;
        int i=array.length-1,j=0;
        while(i>=0 && j<array[0].length){
            if(array[i][j]==target){
                return true;
            }else if(array[i][j]>target)
                i--;
            else
                j++;
        }
        return false;
    }
}

100.数组中的逆序对

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。并将P对1000000007取模的结果输出。 即输出P mod 1000000007
在这里插入图片描述

public class Solution {
    int num = 1000000007;
    public int InversePairs(int [] array) {
        return MergeSort(0,array.length-1,array)%num;
    }
    public int MergeSort(int left,int right,int[] arr){
        if(left>=right) return 0;
        int mid = left + (right-left)/2;
        return MergeSort(left,mid,arr)+MergeSort(mid+1,right,arr)+Merge(left,mid,right,arr);
    }
    public int Merge(int left,int mid,int right,int[] arr){
        int res = 0;
        int i=left,j=mid+1,k=0;
        int[] temp = new int[right-left+1];
        while(i<=mid && j<=right){
            if(arr[i]<=arr[j])
                temp[k++] = arr[j++];
            else{
                temp[k++] = arr[i++];
                res += (right-j+1);
                res %= num;
            }
        }
        while(i<=mid)
            temp[k++] = arr[i++];
        while(j<=right)
            temp[k++] = arr[j++];
        for(int t=0;t<temp.length;t++)
            arr[left+t] = temp[t];
        return res;
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值