> 文档中心 > NC刷题笔记14-其他算法

NC刷题笔记14-其他算法

NC刷题笔记14-其他算法

    • 1 KMP
    • 2 替换空格
    • 3 最长公共前缀
    • 4 回文
      • 4.1 最长回文串
      • 4.2 验证回文串
      • 4.3 最长回文子串
      • 4.4 最长回文子序列
    • 5 括号匹配
    • 6 把字符串转换成整数
    • 7 随机算法Knuth
    • 8 堆排序
    • 9 快速排序
    • 10 归并排序
    • 11 堆Java实现

1 KMP

思路:字符串A和字符串B匹配的过程中不需要从头开始,如果已经匹配过的字符字串有前后缀相同的部分,就从公共前后缀后面的位置开始匹配
/ * @Author 丁永新 * @Date 2022/2/22 */public class KMP {    /     * 求出一个字符数组的next数组     * @param t 字符数组     * @return next数组     */    public static int[] getNextArray(char[] t) { int[] next = new int[t.length]; next[0] = -1; next[1] = 0; int k; for (int j = 2; j < t.length; j++) {     k=next[j-1];     while (k!=-1) {  if (t[j - 1] == t[k]) {      next[j] = k + 1;      break;  }else {      k = next[k];  }  next[j] = 0;  //当k==-1而跳出循环时,next[j] = 0,否则next[j]会在break之前被赋值     } } return next;    }    /     * 对主串s和模式串t进行KMP模式匹配     * @param s 主串     * @param t 模式串     * @return 若匹配成功,返回t在s中的位置(第一个相同字符对应的位置),若匹配失败,返回-1     */    public static int kmpMatch(String s, String t){ char[] s_arr = s.toCharArray(); char[] t_arr = t.toCharArray(); int[] next = getNextArray(t_arr); int i = 0, j = 0; while (i<s_arr.length && j<t_arr.length){     if(j == -1 || s_arr[i]==t_arr[j]){  i++;  j++;     }else  j = next[j]; } if(j == t_arr.length) return i-j; else return -1;    }    public static void main(String[] args) { System.out.println(kmpMatch("abcabaabaabcacb", "abaabcac"));    }}

2 替换空格

/ * @Author 丁永新 * @Date 2022/2/22 */public class Main {    /     * 方法1 逐个检查     * @param str     * @return     */    public String Replacespace0(String str){ if(str==null||str.length()==0) return str; StringBuilder sb=new StringBuilder(); for(int i=0;i<str.length();i++){     if(String.valueOf(str.charAt(i)).equals(" ")){  sb.append("%20");     }else{  sb.append(str.charAt(i));     } } return sb.toString();    }    /     * 方法2 调用API     * @param str     * @return     */    public String Replacespace1(String str){ return str.replaceAll(" ","%20");    }}

3 最长公共前缀

思路:1 先判空2 排序3 比较最短和最长的两个字符串公共前缀
public class Main1 {    public static String LongestPrifix(String[] strings){ if(strings==null||strings.length==0||judgeEmpty(strings)) return ""; Arrays.sort(strings); int n=Math.min(strings[0].length(),strings[strings.length-1].length()); StringBuilder sb=new StringBuilder(); for(int i=0;i<n;i++){     if(strings[0]==strings[strings.length-1]) sb.append(strings[0].charAt(i));     else break; } return sb.toString();    }    public static boolean judgeEmpty(String[] strings){ for(String s:strings){     if(s==null||s.equals("")||s.length()==0) return false; } return true;    }}

4 回文串

4.1 最长回文串

题目给定一个包含大写字母和小写字母的字符串,找到通过这些字母构造成的最长的回文串。在构造过程中,请注意区分大小写输入: "abccccdd"输出: 7解释: 我们可以构造的最长的回文串是"dccaccd", 它的长度是 7
思路:1 偶数个字符结果+22 存在奇数个字符结果+13 返回结果
    public static int HuiWenString(String str){ if(str==null||str.equals("")) return 0; HashSet<Character> set=new HashSet<>(); int result=0; for(int i=0;i<str.length();i++){     char c=str.charAt(i);     if(set.contains(c)){  set.remove(c);  result+=2;     }else{  set.add(c);     } } return set.size()==0?result:result+1;    }

4.2 验证回文串

LeetCode: 给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。 说明:本题中,我们将空字符串定义为有效的回文串。输入: "A man, a plan, a canal: Panama"输出: true
public class Main3 {    public static boolean HuiWenString(String str){ str=str.toLowerCase(); int i=0,j=str.length()-1; while(i<j){     while(!Character.isLetterOrDigit(str.charAt(i))) i++;     while(!Character.isLetterOrDigit(str.charAt(j))) j--;     if(str.charAt(i)!=str.charAt(j)) return false;     i++;     j--; } return true;    }    public static void main(String[] args) { System.out.println(HuiWenString("A man, a plan, a canal: Panama"));    }}

4.3 最长回文子串

思路:中心扩散法,奇数和偶数
public class LongestHuiWenString {    private int index, len;    public String longestPalindrome(String s) { if (s.length() < 2)     return s; for (int i = 0; i < s.length() - 1; i++) {     PalindromeHelper(s, i, i);     PalindromeHelper(s, i, i + 1); } return s.substring(index, index + len);    }    public void PalindromeHelper(String s, int l, int r) { while (l >= 0 && r < s.length() && s.charAt(l) == s.charAt(r)) {     l--;     r++; } if (len < r - l - 1) {     index = l + 1;     len = r - l - 1; }    }    }

4.4 最长回文子序列

思路:动态规划dp[i][i]=dp[i+1][j-1]+2;dp[i][j]=Math.max(dp[i+1][j],dp[i][j-1]);
class Solution {    public int longestPalindromeSubseq(String s) { int len = s.length(); int [][] dp = new int[len][len]; for(int i = len - 1; i>=0; i--){     dp[i][i] = 1;     for(int j = i+1; j < len; j++){  if(s.charAt(i) == s.charAt(j))      dp[i][j] = dp[i+1][j-1] + 2;  else      dp[i][j] = Math.max(dp[i+1][j], dp[i][j-1]);     } } return dp[0][len-1];    }}

5 括号匹配

爱奇艺 2018 秋招 Java:一个合法的括号匹配序列有以下定义: 1 空串""是一个合法的括号匹配序列 2 如果"X"和"Y"都是合法的括号匹配序列,"XY"也是一个合法的括号匹配序列 3 如果"X"是一个合法的括号匹配序列,那么"(X)"也是一个合法的括号匹配序列 4 每个合法的括号序列都可以由以上规则生成。 例如: "","()","()()","((()))"都是合法的括号序列对于一个合法的括号序列我们又有以下定义它的深度: 1 空串""的深度是0 2 如果字符串"X"的深度是x,字符串"Y"的深度是y,那么字符串"XY"的深度为max(x,y) 3 如果"X"的深度是x,那么字符串"(X)"的深度是x+1 例如: "()()()"的深度是1,"((()))"的深度是3。牛牛现在给你一个合法的括号序列,需要你计算出其深度
public class Main {    public static void main(String[] args) { Scanner sc = new Scanner(System.in); String s = sc.nextLine(); int cnt = 0, max = 0, i; for (i = 0; i < s.length(); ++i) {     if (s.charAt(i) == '(')  cnt++;     else  cnt--;     max = Math.max(max, cnt); } sc.close(); System.out.println(max);    }}

6 把字符串转换成整数

    public static int StrToInt(String str) { if (str.length() == 0) return 0; char[] chars = str.toCharArray(); int flag = 0;   // 判断是否存在符号位 if (chars[0] == '+')  flag = 1; else if (chars[0] == '-')  flag = 2; int start = flag > 0 ? 1 : 0; int res = 0;    // 保存结果 for (int i = start; i < chars.length; i++) {     if (Character.isDigit(chars[i])) {    // 调用Character.isDigit(char)方法判断是否是数字,是返回True,否则False  int temp = chars[i] - '0';  res = res * 10 + temp;     } else {  return 0;     } } return flag != 2 ? res : -res;    }

7 随机算法Knuth

思路:倒序遍历数组,随机获取前面的元素与当前元素进行交换时间复杂度:O(n)空间复杂度:O(1)
    public static void RandomArray(int[] array){ Random random = new Random(); for(int i=array.length-1; i>=0; i--){     int index=random.nextInt(array.length)%(i+1);     int temp=array[i];     array[i]=array[index];     array[index]=temp;    }

8 堆排序

/ * @Author 丁永新 * @Date 2022/3/14 */public class HeapSort {    public static void main(String[] args) { int[] nums=new int[]{1,8,5,3,7,2,0,1}; HeapSort h=new HeapSort(); h.buildMaxHeap(nums,nums.length); for(int i:nums) System.out.println(i);    }    public void buildMaxHeap(int[] a, int heapSize) { //调整成顶堆形式 for (int i = heapSize / 2; i >= 0; --i) {     maxHeapify(a, i, heapSize); } //堆调整 for (int j = a.length - 1; j >= 0; j--) {     swap(a, 0, j);     maxHeapify(a, 0, j); }    }    //大顶堆函数    public void maxHeapify(int[] a, int i, int heapSize) { int l = i * 2 + 1, r = i * 2 + 2, largest = i; if (l < heapSize && a[l] > a[largest]) largest = l; if (r < heapSize && a[r] > a[largest]) largest = r; if (largest != i) {     swap(a, i, largest);     maxHeapify(a, largest, heapSize); }    }    //定义一个交换函数    public void swap(int[] a, int i, int j) { int temp = a[i]; a[i] = a[j]; a[j] = temp;    }}

9 快速排序

    public void quicksort(int[] a,int left,int right){ int l=left,r=right,povit=a[(l+r)/2]; while(l<r){     while(a[l]>povit) l++;     while(a[r]<povit) r--;     if (l >= r) break;     int temp=a[l];     a[l]=a[r];     a[r]=temp;     if(a[l]==povit) r--;     if(a[r]==povit) l++; } if(l==r){     l++;     r--; } if(l<right) quicksort(a,l,right); if(r>left) quicksort(a,left,r);    }

10 归并排序

public class Solution {    public void sort(int [] array) { mergeSort(array,0,array.length-1);    } public void mergeSort(int[] array,int begin,int last){ if(begin>=last) return; int mid=begin+(last-begin)/2; mergeSort(array,begin,mid); mergeSort(array,mid+1,last); merge(array,begin,mid,last);    } public void merge(int[] array,int begin,int mid,int last){ int[] tempArray=new int[last-begin+1]; int i=begin,j=mid+1,k=0; while(i<=mid&&j<=last){     if(array[i]<=array[j]){  tempArray[k++]=array[i++];     }else{  tempArray[k++]=array[j++];  res=(res+mid-i+1)%1000000007;     } } while(j<=last){    tempArray[k++]=array[j++]; } while(i<=mid){    tempArray[k++]=array[i++]; } for(int k1=0;k1<tempArray.length;k1++){     array[begin+k1]=tempArray[k1]; }    }}

11 堆Java实现

package BP;import java.util.Arrays;/ * @Author 丁永新 * @Date 2022/3/19 */public class BinaryTree {    public static void main(String[] args) { int[] num=new int[]{1,8,7,6,5,4,2,3,9}; BinaryTree heap=new BinaryTree(num); System.out.println(heap.toString()); System.out.println("移除元素"); while(heap.size()!=0){     System.out.println(heap.poll()); }  System.out.println(heap.toString()); System.out.println("添加元素"); int index=10; while(index<20){     heap.offer(index++);     System.out.println(heap.peek()); } System.out.println(heap.toString());    }    int[] headNum;    public BinaryTree(int[] nums){ this.headNum = nums; headSort(nums,0,nums.length-1);    }//----------------------移除------------------------------------    public int poll(){ if(headNum.length==0) return -1; int res=headNum[0]; headNum=getRemoveFirstArray(); adjustRemove(0); return res;    }    public void adjustRemove(int i){ int l=2*i+1,r=2*i+2,largest=i; if(l<headNum.length && headNum[l]>headNum[largest]) largest=l; if(r<headNum.length && headNum[r]>headNum[largest]) largest=r; if(largest!=i){     swap(headNum,i,largest);     adjustRemove(largest); }    }    public int[] getRemoveFirstArray(){ swap(headNum,0,headNum.length-1); int[] num=new int[headNum.length-1]; for(int i=0;i<num.length;i++){     num[i]=headNum[i]; } headNum=num; return headNum;    }//----------------------添加------------------------------------    public void offer(int num){ //扩容 addSize(num); //调整最后一个元素 adjustInsert(headNum.length-1);    }    public void addSize(int num){ int[] nums=new int[headNum.length+1]; for(int i=0;i<headNum.length;i++){     nums[i]=headNum[i]; } nums[nums.length-1]=num; this.headNum=nums;    }    public void adjustInsert(int i){ //获取父节点 int parent=getParent(i),largest=i; if(parent==-1) return; if(headNum[parent]<headNum[i]){     largest=parent; } if(largest!=i){     swap(headNum,i,largest);     adjustInsert(largest); }    }    public int getParent(int i){ if(i==0) return -1; if(i==1||i==2) return 0; int left=i-1; int right=i-2; return left%2==0?left/2:right/2;    }//----------------------堆排序  用于初始化数组------------------------------------    public void headSort(int[] nums,int l,int r){ int length=r-l+1; for(int i=nums.length/2;i>=0;i--){     heapFy(nums,i,length); } for(int j=nums.length-1;j>=0;j--){     swap(nums,0,j);     heapFy(nums,0,j); }    }    public void heapFy(int[] nums,int i,int heapSize){ int l=2*i+1,r=2*i+2,largest=i; if(l<heapSize && nums[l]<nums[largest]) largest=l; if(r<heapSize && nums[r]<nums[largest]) largest=r; if(largest!=i){     swap(nums,i,largest);     heapFy(nums,largest,heapSize); }    }//----------------------辅助函数------------------------------------    public void swap(int[] nums,int a,int b){ int temp=nums[a]; nums[a]=nums[b]; nums[b]=temp;    }    public int size(){ return headNum.length;    }    public int peek(){ if(headNum.length==0) return -1; return headNum[0];    }    @Override    public String toString(){ return Arrays.toString(headNum);    }}

4万个成语大全