面试高频算法题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;
}
}