├── 399份简历模板-下载到电脑上解压,内容与文件夹一样.zip ├── README.md ├── 二进制表示中1的个数(网易互娱) ├── 剑指offer_扫描版_6.22M_高清重制.pdf ├── 听谁说笔试 ├── 听谁说笔试(批改试卷) ├── 大数据岗-阿里一面.docx ├── 字节跳动面试算法题目 ├── 小米- ├── 快手笔试 ├── 快排的递归与非递归实现(腾讯面试) ├── 斗鱼笔试编程 ├── 有赞笔试题(字符串压缩) ├── 求两个单链表是否相交-字节跳动 ├── 求最长字串(阿里面试) ├── 汇顶科技(base64Code) ├── 爱奇艺一面.docx ├── 爱奇艺一面面经.txt ├── 牛客网算法.zip ├── 算法临阵磨枪.txt ├── 精通Spring 4.x企业应用开发实战学习笔记.zip ├── 网易春季实习.zip ├── 美团java视频一面.docx ├── 蚂蚁一面面经.docx ├── 蚂蚁金服一到五面.docx ├── 输入一个字符串,求出该字符串包含的字符集合(SHEIN笔试) ├── 阿里一面面经.txt ├── 阿里二面面经.txt ├── 阿里巴巴数据分析一面面经.docx ├── 面经-京东一面.docx ├── 面经-易贝一面.docx ├── 面经-美团一面.txt ├── 面经-美团一面二面.docx ├── 面经-阿里一面.docx ├── 面经-阿里二面.docx ├── 面经-阿里交叉面.docx ├── 面经-阿里终面.docx └── (贝壳笔试) /399份简历模板-下载到电脑上解压,内容与文件夹一样.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/399份简历模板-下载到电脑上解压,内容与文件夹一样.zip -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # leetcode- 2 | 面试笔试常见经典编程题分享~ 3 | 4 | 建议多刷本文给出了,好处多多!! 5 | 6 | 并把认为好的编程题贴到此处 7 | 8 | 便于自己复习,也希望可以帮助到大家 9 | 10 | 不仅有利于自己编程能力的进步,也是为找到好工作定下目标! 11 | -------------------------------------------------------------------------------- /二进制表示中1的个数(网易互娱): -------------------------------------------------------------------------------- 1 | public class Solution { 2 | public int NumberOf1(int n){ 3 | int count == 0; 4 | while(n!=0) { 5 | count++; 6 | n = n & (n-1); 7 | } 8 | return count; 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /剑指offer_扫描版_6.22M_高清重制.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/剑指offer_扫描版_6.22M_高清重制.pdf -------------------------------------------------------------------------------- /听谁说笔试: -------------------------------------------------------------------------------- 1 | 捡贝壳 2 | 3 | 4 | 5 | public static void main(String[] args) { 6 | 7 | Scanner scanner = new Scanner(System.in); 8 | 9 | int variety = scanner.nextInt(); 10 | int volume = scanner.nextInt(); 11 | 12 | int[] nums = new int[variety]; 13 | int[] vos = new int[variety]; 14 | 15 | for (int i = 0; i < variety; i++) { 16 | 17 | nums[i] = scanner.nextInt(); 18 | vos[i] = scanner.nextInt(); 19 | } 20 | 21 | 22 | int currentv = 0; 23 | int count = 0; 24 | for (int j = 0; j < variety; j++) { 25 | 26 | for (int n = 0; n < nums[j]; n++) { 27 | int t = vos[j] + currentv; 28 | if (t > volume) break; 29 | currentv = t; 30 | count++; 31 | } 32 | } 33 | 34 | System.out.println(count); 35 | 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /听谁说笔试(批改试卷): -------------------------------------------------------------------------------- 1 | import java.util.Scanner; 2 | 3 | 4 | public class Main{ 5 | 6 | public static void main(String[] args){ 7 | Scanner in = new Scanner(System.in); 8 | int n = in.nextInt(); 9 | String [] strArray = new String[n]; 10 | 11 | for(int i =0 ; i < n; i++){ 12 | strArray[i] = in.nextLine(); 13 | } 14 | 15 | int[] score = new int[n]; 16 | for(int i =0 ; i =0&&a[pos-1]%2==0) 11 | { 12 | int tmp=a[pos]; 13 | a[pos]=a[pos-1]; 14 | a[pos-1]=tmp; 15 | --pos; 16 | } 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /小米-: -------------------------------------------------------------------------------- 1 | //有一行由 N 个数字组成的数字字符串,字符串所表示的数是一正整数。移除字符串中的 K 个数字,使剩下的数字是所有可能中最小的。 2 | 3 | 4 | import java.util.*; 5 | 6 | public class Main{ 7 | 8 | public static void main(String[] args){ 9 | Scanner in = new Scanner(System.in); 10 | String s = in.nextLine(); 11 | 12 | System.out.println(solution(s)); 13 | 14 | } 15 | public static String solution(String line) { 16 | String[] strs = line.split(","); 17 | String strcount = strs[1].trim(); 18 | int count = Integer.valueOf(strcount); 19 | char[] charArr = strs[0].toCharArray(); 20 | long len = strs[0].length(); 21 | 22 | if (len == count) { 23 | return 0 + ""; 24 | } 25 | int index = 0; 26 | int i = 1; 27 | while (index < count && i < len) { 28 | if (charArr[i - 1] <= charArr[i]) { 29 | if (i + count == len) { 30 | for (;i < len - index; i++) { 31 | if(i == len - index - 1){ 32 | charArr[i] = ' '; 33 | }else { 34 | charArr[i] = charArr[i + 1]; 35 | } 36 | } 37 | index++; 38 | i=1; 39 | } else { 40 | i++; 41 | } 42 | } else { 43 | for(int j=i-1; j list = new ArrayList<>(); 11 | char[] chars = string.toCharArray();//将字符串转化成字符数组 12 | for (int i = 0; i < chars.length; i++) { 13 | char aChar = chars[i]; 14 | list.add(aChar);//将字符数组元素添加到集合中 15 | } 16 | for ( int i = 0 ; i < list.size() - 1 ; i ++ ) { 17 | for ( int j = list.size() - 1 ; j > i; j -- ) { 18 | if (list.get(j).equals(list.get(i))) { 19 | list.remove(j); 20 | } 21 | } 22 | } 23 | for (int i = 0; i < list.size(); i++) {//遍历集合取出每个字符 24 | int count = 0;//定义计数器 25 | Character character = list.get(i); 26 | for (int j = 0; j < chars.length; j++) {//遍历数组取出每个字符和集合中的元素比较 27 | char aChar = chars[j]; 28 | if (character.equals(aChar)){//如果集合中的元素有等于数组中的字符,计数器加1 29 | count++; 30 | } 31 | } 32 | if(i==list.size()-1) 33 | System.out.println(character + ":" + count );//打印结果 34 | else 35 | System.out.println(character + ":" + count + ",");//打印结果 36 | } 37 | 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /快排的递归与非递归实现(腾讯面试): -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | //快排的实现 3 | public class quikSort{ 4 | 5 | //(1)递归实现快速排序 6 | public static void quickSort(int[]s,int l,int r){ 7 | 8 | if(lpivot) //从右向左 16 | j--; 17 | if(j>i) 18 | { 19 | s[i++]=s[j]; 20 | } 21 | while(i stack = new LinkedList(); //用栈模拟 38 | if(start < end) { 39 | stack.push(end); 40 | stack.push(start); 41 | while(!stack.isEmpty()) { 42 | int l = stack.pop(); 43 | int r = stack.pop(); 44 | int index = partition(a, l, r); 45 | if(l < index - 1) { 46 | stack.push(index-1); 47 | stack.push(l); 48 | } 49 | if(r > index + 1) { 50 | stack.push(r); 51 | stack.push(index+1); 52 | } 53 | } 54 | } 55 | } 56 | 57 | public static int partition(int[] a, int start, int end) { 58 | int pivot = a[start]; 59 | while(start < end) { 60 | while(start < end && a[end] >= pivot) 61 | end--; 62 | a[start] = a[end]; 63 | while(start < end && a[start] <= pivot) 64 | start++; 65 | a[end] = a[start]; 66 | } 67 | a[start] = pivot; 68 | return start; 69 | } 70 | //打印数组的值 71 | public static void PrintArray(int[]arr) 72 | { 73 | for(int i=0;i 6 | #include 7 | 8 | int main() 9 | { 10 | char i,j,k; 11 | for(i='x';i<='z';i++) 12 | { 13 | for(j='x';j<='z';j++) 14 | { 15 | if(i!=j) 16 | { 17 | for(k='x';k<='z';k++) 18 | { 19 | if(i!=k && j!=k) 20 | { 21 | if(i!='x' && k!='x' && k!='z') 22 | { 23 | printf("顺序为:a--%c\tb--%c\tc--%c\n",i,j,k); 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /有赞笔试题(字符串压缩): -------------------------------------------------------------------------------- 1 | public void zipString() { 2 | String data="AAABBBaaaeeefssaaffss"; 3 | char[] dst = new char[data.length()]; 4 | data.getChars(0,data.length(),dst,0); 5 | List infos = new ArrayList(); 6 | int j = 1; 7 | for(int i = 0;i1){ 27 | builder.append(info.b).append(info.count); 28 | }else{ 29 | builder.append(info.b); 30 | } 31 | } 32 | System.out.println(builder.toString()); 33 | } 34 | 35 | class ByteInfo { 36 | char b; 37 | int count; 38 | int pos; 39 | } 40 | -------------------------------------------------------------------------------- /求两个单链表是否相交-字节跳动: -------------------------------------------------------------------------------- 1 | typedef struct node_t 2 | { 3 | int data;//data 4 | struct node_t *next; //next 5 | }node; 6 | 7 | node* find_node(node *head1, node *head2) 8 | { 9 | //链表带头节点 10 | if(head1==NULL || head2==NULL) 11 | { 12 | return NULL;//如果有为空的链表,肯定是不相交的 13 | } 14 | node *p1, *p2; 15 | p1 = head1; 16 | p2 = head2; 17 | int len1 = 0; 18 | int len2 =0; 19 | int diff = 0; 20 | while(p1->next!=NULL) 21 | { 22 | p1 = p1->next; 23 | len1++; 24 | } 25 | while(p2->next!=NULL) 26 | { 27 | p2 = p2->next; 28 | len2++; 29 | } 30 | if(p1 != p2) //如果最后一个节点不相同,返回NULL 31 | { 32 | return NULL; 33 | } 34 | diff = abs(len1 - len2); 35 | if(len1 > len2) 36 | { 37 | p1 = head1; 38 | p2 = head2; 39 | } 40 | else 41 | { 42 | p1 = head2; 43 | p2 = head1; 44 | } 45 | for(int i=0; inext; 48 | } 49 | while(p1 != p2) 50 | { 51 | p1 = p1->next; 52 | p2 = p2->next; 53 | } 54 | return p1; 55 | } 56 | -------------------------------------------------------------------------------- /求最长字串(阿里面试): -------------------------------------------------------------------------------- 1 | import java.util.HashMap; 2 | import java.util.List; 3 | import java.util.Map; 4 | import java.util.Scanner; 5 | import java.util.TreeMap; 6 | public class Main { 7 | public static void main(String[] args) { 8 | String str1 = "gdfggf3af3eeabc"; 9 | max_unique_substring(str1); 10 | 11 | } 12 | 13 | 14 | static void max_unique(String str) 15 | { 16 | // begin用来保存 最长不重复子串的 开始索引 17 | int begin=0; 18 | // maxlen用来保存最长不重复子串的 长度 19 | int maxlen = 0; 20 | // 定义一个容器,用来保存遍历时候遇到的每一个字符的出现次数情况 21 | TreeMap tm = new TreeMap(); 22 | int n = str.length(); 23 | 24 | int j=0; 25 | for(int i=0; i maxlen) 45 | { 46 | maxlen = j-i; 47 | begin = i; 48 | } 49 | } 50 | System.out.println(maxlen + " " + str.substring(begin, begin+maxlen)) ; 51 | 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /汇顶科技(base64Code): -------------------------------------------------------------------------------- 1 | import java.util.*; 2 | 3 | public class Main{ 4 | 5 | private static final String base64Code= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 6 | 7 | public static String encode(String srcStr) { 8 | //有效值检查 9 | if(srcStr == null || srcStr.length() == 0) { 10 | return srcStr; 11 | } 12 | //将明文的ASCII码转为二进制位字串 13 | char[] srcStrCh= srcStr.toCharArray(); 14 | StringBuilder asciiBinStrB= new StringBuilder(); 15 | String asciiBin= null; 16 | for(int i= 0; i< srcStrCh.length; i++) { 17 | asciiBin= Integer.toBinaryString((int)srcStrCh[i]); 18 | while(asciiBin.length()< 8) { 19 | asciiBin= "0"+ asciiBin; 20 | } 21 | asciiBinStrB.append(asciiBin); 22 | } 23 | //跟据明文长度在二进制位字串尾部补“0” 24 | while(asciiBinStrB.length()% 6!= 0) { 25 | asciiBinStrB.append("0"); 26 | } 27 | String asciiBinStr= String.valueOf(asciiBinStrB); 28 | //将上面得到的二进制位字串转为Value,再跟据Base64编码表将之转为Encoding 29 | char[] codeCh= new char[asciiBinStr.length()/ 6]; 30 | int index= 0; 31 | for(int i= 0; i< codeCh.length; i++) { 32 | index= Integer.parseInt(asciiBinStr.substring(0, 6), 2); 33 | asciiBinStr= asciiBinStr.substring(6); 34 | codeCh[i]= base64Code.charAt(index); 35 | } 36 | StringBuilder code= new StringBuilder(String.valueOf(codeCh)); 37 | //跟据需要在尾部添加“=” 38 | if(srcStr.length()% 3 == 1) { 39 | code.append("=="); 40 | } else if(srcStr.length()% 3 == 2) { 41 | code.append("="); 42 | } 43 | //每76个字符加一个回车换行符(CRLF) 44 | int i= 76; 45 | while(i< code.length()) { 46 | code.insert(i, "\r\n"); 47 | i+= 76; 48 | } 49 | code.append("\r\n"); 50 | return String.valueOf(code); 51 | } 52 | 53 | public static String decode(String srcStr) { 54 | //有效值检查 55 | if(srcStr == null || srcStr.length() == 0) { 56 | return srcStr; 57 | } 58 | //检测密文中“=”的个数后将之删除,同时删除换行符 59 | int eqCounter= 0; 60 | if(srcStr.endsWith("==")) { 61 | eqCounter= 2; 62 | } else if(srcStr.endsWith("=")) { 63 | eqCounter= 1; 64 | } 65 | srcStr= srcStr.replaceAll("=", ""); 66 | srcStr= srcStr.replaceAll("\r\n", ""); 67 | //跟据Base64编码表将密文(Encoding)转为对应Value,然后转为二进制位字串 68 | char[] srcStrCh= srcStr.toCharArray(); 69 | StringBuilder indexBinStr= new StringBuilder(); 70 | String indexBin= null; 71 | for(int i= 0; i< srcStrCh.length; i++) { 72 | indexBin= Integer.toBinaryString(base64Code.indexOf((int)srcStrCh[i])); 73 | while(indexBin.length()< 6) { 74 | indexBin= "0"+ indexBin; 75 | } 76 | indexBinStr.append(indexBin); 77 | } 78 | //删除因编码而在尾部补位的“0”后得到明文的ASCII码的二进制位字串 79 | if(eqCounter == 1) { 80 | indexBinStr.delete(indexBinStr.length()- 2, indexBinStr.length()); 81 | } else if(eqCounter == 2) { 82 | indexBinStr.delete(indexBinStr.length()- 4, indexBinStr.length()); 83 | } 84 | String asciiBinStr= String.valueOf(indexBinStr); 85 | //将上面得到的二进制位字串分隔成字节后还原成明文 86 | String asciiBin= null; 87 | char[] ascii= new char[asciiBinStr.length()/ 8]; 88 | for(int i= 0; i< ascii.length; i++) { 89 | asciiBin= asciiBinStr.substring(0, 8); 90 | asciiBinStr= asciiBinStr.substring(8); 91 | ascii[i]= (char)Integer.parseInt(asciiBin, 2); 92 | } 93 | return String.valueOf(ascii); 94 | } 95 | 96 | public static void main(String[] args) { 97 | 98 | Scanner in = new Scanner(System.in); 99 | String s = in.nextLine(); 100 | System.out.print(encode(s)); 101 | 102 | } 103 | 104 | } 105 | -------------------------------------------------------------------------------- /爱奇艺一面.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/爱奇艺一面.docx -------------------------------------------------------------------------------- /爱奇艺一面面经.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/爱奇艺一面面经.txt -------------------------------------------------------------------------------- /牛客网算法.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/牛客网算法.zip -------------------------------------------------------------------------------- /算法临阵磨枪.txt: -------------------------------------------------------------------------------- 1 | ———— 2 | 3 | 字典树: 4 | 特性: 5 | 1、字典树用边表示字母 6 | 2、有相同前缀的单词公用前缀节点,那我们可以的得出每个节点最多有26个子节点(在单词只包含小写字母的情况下) 7 | 3、整棵树的根节点是空的。为什么呢?便于插入和查找,这将会在后面解释。 8 | 4、每个单词结束的时候用一个特殊字符表示,图中用的‘$’,那么从根节点到任意一个‘$’所经过的边的所有字母表示一个单词。 9 | 编号方式: 10 | trie[i][j] = k; 11 | 1、编号为i的节点的第j个孩子是编号为k的节点,相同字母编号可能不同,编号为i, k 12 | 2、编号为i的节点的第j个孩子是编号为k的节点,相同字母编号相同,编号为i 13 | 插入新单词: 14 | void insert() // 采用第一种编号方式,id为孩子的次序,root为当前节点的编号,trie[root][id]为当前节点的第id个孩子的节点的编号 15 | { 16 | len = strlen(s);//单词s的长度 17 | root = 0;//根节点编号为0 18 | for(int i = 0;i < len; i++) { 19 | int id = s[i] - 'a'; //id为当前节点的孩子的编号 20 | if(!trie[root][id]) //如果之前没有从root到id的前缀 21 | trie[root][id] = ++tot; //插入,tot即为第一种编号的计数器 22 | root = trie[root][id]; //顺着字典树往下走 23 | } 24 | } 25 | 查找前缀是否出现过: 26 | bool find() 27 | { 28 | len = strlen(s); 29 | root = 0; //从根结点开始找 30 | for(int i = 0; s[i]; i++) { 31 | int id = s[i] - 'a'; 32 | if(trie[root][x] == 0) //其实查找不过就是变形的插入 33 | return false; //以root为头结点的x字母不存在,返回0 34 | root = trie[root][x]; //为查询下个字母做准备,往下走 35 | } 36 | return true;//找到了 37 | } 38 | 查询某个单词是否出现过: 39 | 我们用bool变量 v[i]表示节点i是否是单词结束的标志。 //i就是节点的编号,也就是上边代码中的tot 40 | 那么最后return的是v[root],所以在插入操作中插入完每个单词是,要对单词最后一个字母的v[i]置为true,其他的都是false 41 | 查询前缀出现的次数: 42 | 开一个sum[i],表示位置i被访问过的次数, 43 | 那么最后return的是sum[root],插入操作中每访问一个节点,都要让他的sum++ 44 | 这里前缀的次数是标记在前缀的最后一个字母所在位置的后一个位置上。 45 | 46 | 47 | —————— 48 | 49 | 红黑树: 50 | 特性: 51 | 1、每个节点是黑色或者红色 52 | 2、根节点是黑色 53 | 3、每个叶节点(空节点)是黑色 54 | 4、如果一个节点是红色的,那个他的子节点必须是黑色的 55 | 5、从一个节点到该节点的子孙节点的所有路径上包含相同数目的黑节点 56 | 注意: 57 | 1、特性3的叶子节点是指空节点 58 | 2、特性5可以确保没有一条路径会比其他路径长出两倍,因而红黑树是接近平衡的二叉树 59 | 时间复杂度: 60 | O(lgn) 61 | 红黑树的左旋和右旋: 62 | 左旋中的左,意味着被旋转的节点将从子树的根节点变成一个左节点 63 | 右旋中的右,意味着被旋转的节点将从子树的根节点变成一个右节点 64 | 具体算法: 65 | 还没什么时间看 66 | 67 | —————— 68 | 69 | 字符串匹配算法: 70 | 71 | BF: 72 | 朴素算法,不赘述,辣鸡 73 | 该算法之所以慢,是因为只关心有效的位移,而不关心无效的位移 74 | 75 | KMP: 76 | 经典算法,不再赘述 77 | 基本思想就是充分利用目标字符串的特性,利用最长前后缀公共元素长度来建立匹配失败的时候的next数组,根据next数组进行匹配 78 | 时间复杂度: 79 | O(m+n) 80 | 81 | Rabin-karp算法: 82 | 基本思路: 83 | 假设子串的长度为M,目标字符串的长度为N 84 | 计算字串的HASH值 85 | 计算目标字符串中每个长度为M的子串的HASH值,共需要计算N-M+1次,因为长度不足N的时候不需要计算 86 | 比较HASH值 87 | 如果HASH值不同,则必然不匹配,如果HASH值相同,则需要用朴素算法再次判断 88 | 加快HASH计算速度: 89 | Rabin-Karp算法并不是对目标字符串的每一个长度为M的子串都重新计算hash值,而是在前几个字串的基础之上,计算下一个子串的hash值 90 | 这就加快了HASH的计算速度,将朴素算法中的内循环的时间复杂度从O(M)降到了O(1)。 91 | 时间复杂度: 92 | 平均时间复杂度:O(M+N) 93 | 94 | BM算法: 95 | SUNDAY算法就脱胎其中,但是还没具体了解 96 | 97 | SUNDAY算法: 98 | 核心思想: 99 | 在匹配过程中,模式串发现不匹配时,算法能跳过尽可能多的字符以进行下一步的匹配,从而提高了匹配效率。 100 | 基本思路: 101 | THIS_IS_A_SIMPLE_EXAMPLE 102 | EXAMPLE 103 | 原字符串和子串左端对齐,发现不匹配后检测原字符串的下一个字符“_”是否在子串中出现,没有出现,则直接将字符串移动到下一个位置 104 | THIS_IS_A_SIMPLE_EXAMPLE 105 | EXAMPLE 106 | 移动之后发现还是不匹配,但是原字符串的下一个字符“E”在子串中出现了,那么移动子串靠后的字符与原子串对齐 107 | 这样从头逐个开始比较,最终匹配成功 108 | 时间复杂度: 109 | 最坏时间复杂度:O(MN) 110 | 最好时间复杂度:O(N) 111 | 平均时间复杂度:O(M+N) 112 | 113 | —————— 114 | 115 | 排序算法: 116 | 算法 平均时间复杂度 最好 最坏 空间复杂度 排序方式 稳定性 117 | 冒泡排序 O(n2) O(n) O(n2) O(1) 内排序 稳定 118 | 选择排序 O(n2) O(n2) O(n2) O(1) 内排序 不稳定 119 | 插入排序 O(n2) O(n) O(n2) O(1) 内排序 稳定 120 | 希尔排序 O(nlogn) O(nlog2n) O(nlog2n) O(1) 内排序 不稳定 121 | 归并排序 O(nlogn) O(nlogn) O(nlogn) O(n) 外排序 稳定 122 | 快速排序 O(nlogn) O(nlogn) O(n2) O(logn) 内排序 不稳定 123 | 堆排序 O(nlogn) O(nlogn) O(nlogn) O(1) 内排序 不稳定 124 | 基数排序 O(d(n+rd)) O(d(n+rd)) O(d(n+rd)) O(rd) 内排序 稳定 125 | 126 | 基数排序: 127 | 基本思想: 128 | 也叫桶排序,采用了多关键字排序的思想,举个例子解释什么是多关键字排序: 129 | 一副有有花色并且有数值的扑克要按花色和数值进行排序,那么可以先按面值分成13堆,将13堆牌从小到大叠在一起,然后将整副牌颠倒过来,按花色分成四堆,再按从小到大的顺序合并,这样就得到了满足要求的牌。 130 | 对关键字排序分两种: 131 | 最高位优先(MSD): 132 | 先对最主位关键字K0排序,形成具有相同K0值的多个子序列,然后就每个子序列对关键字K1进行排序,依次重复 133 | 最低位优先(LSD): 134 | 从最次为关键字Kd-1进行排序,然后对高一位关键字Kd-2进行排序,依次重复,知道对K0排序后形成一个有序序列 135 | 不同点: 136 | 若按照MSD排序,必须将序列逐层分为多个子序列,然后对各个子序列进行排序;而用LSD进行排序时,不必分成子序列,每个关键字都是整个序列参加 137 | 在基数排序中使用的是最低位优先的思想。 138 | 基数排序: 139 | 基数排序则是通过“分配”和“收集”两种操作对单逻辑关键字进行排序的一种内部排序方法,因为有的关键字可以看作是多个逻辑关键字复合而成。 140 | 如果关键字是数值,则可以把每一个十进制数字看作关键字,也就是说,一个三位数是由三个关键字构成,分别是它的个位数、十位数、百位数。 141 | 由于分解而成的每个关键字都在同一个范围内(0~9),因而用LSD更为合适。 142 | 算法过程: 143 | 我们需要给待排序的记录准备10个桶,分别代表数字(0~9),对应着待排序记录中每一位的数值。 144 | 先按照记录的个位进行分配,根据每个数的个位决定它加入哪个桶中,然后进行收集 145 | 之后按照十位进行分配,位数不足的补0,然后进行收集,以此类推 146 | 算法空间的优化: 147 | 该算法由于需要准备桶,所以最初没有对算法空间复杂度进行优化时,需要一个10*n的二维数组作为临时空间。 148 | 教材上使用“链式基数排序”的方法大大减少的空间的占用。 149 | 时间复杂度: 150 | O(d(n+rd)): 151 | d:每个记录中含有的关键字的个数 152 | n:记录的个数 153 | rd:每个关键字的取值范围 154 | 155 | —————— 156 | 157 | 图: 158 | 基本概念: 159 | 无向图: 160 | 完全图:有0.5n(n-1)条边的无向图 161 | 稀疏图:很少条边或弧 162 | 稠密图:有较多的边或弧 163 | 权:与图的边或弧相关的数 164 | 连通:节点到节点之间有路径 165 | 连通图:任意两个节点之间都是连通的 166 | 连通分量:无向图中的极大连通子图 167 | 生成树:极小连通子图 168 | 网:带权的图通常称为网 169 | 有向图: 170 | 强连通图:任意两个节点都存在路径 171 | 强连通分量:有向图中的极大强连通子图 172 | 存储结构: 173 | 数组表示法: 174 | 也叫邻接矩阵,表示n个顶点信息和n2个弧信息的存储量 175 | 无向图: 176 | 可以用压缩存储的方式值存入矩阵的下三角元素 177 | 有向图: 178 | 有向图行非零元素表示出度,列非零元素表示入度 179 | 邻接表: 180 | 是一种链式存储结构 181 | 182 | 搜索: 183 | 时间复杂度: 184 | 邻接矩阵作图: 185 | 查找每个顶点的邻接点所需的时间为O(n^2) 186 | 邻接表作图: 187 | 查找每个顶点的邻接点的时间为O(e),此时深度优先遍历的时间复杂度为O(n+e) 188 | 深度优先搜索: 189 | 类似树的先序遍历,是树的先序遍历的推广 190 | 广度优先搜索: 191 | 类似树的层次遍历的过程 192 | DFS和BFS: 193 | 深搜和广搜的时间复杂度相同,区别只在于对顶点的访问数序的不同 194 | 195 | 图的连通性: 196 | 连通图是指,在途中任一顶点出发,进行DFS或BFS,便可以访问到图中所有顶点。 197 | 生成树: 198 | 无向连通图的一个子图如果是一颗包含原图的所有顶点的树,则该子图称为原图的生成树。 199 | 通过DFS得到的是深度优先生成树 200 | 通过BFS得到的是广度优先生成树 201 | 202 | 最小生成树(MST): 203 | 最小生成树问题就是,构造连通网的最小代价生成树的问题,一棵生成树的代价就是树上各边代价的和 204 | 原则: 205 | 选择n-1条边构成最小生成树 206 | 尽量选择权值最小的边,但不能构成回路 207 | MST的性质: 208 | 假设N=(V,{E})是一个连通网,U是顶点集V的一个非空子集,如果(u,v)是一条具有最小权值的边,则必定存在一颗包含便(u,v)的最小生成树。 209 | 下边的两种最小生成树算法都使用了MST性质 210 | 最小生成树算法: 211 | 普里姆算法: 212 | 基本思想: 213 | 以顶点为主导,按照逐个将顶点连通的方式来构建最小生成树 214 | 实现步骤: 215 | 从图中某一顶点出发,选择你则和他关联的具有最小权的边,将其顶点加入到生成树的顶点集合U中 216 | 之后每一步,都从“一个顶点在U中,二另一个顶点不在U的各条边”中选择权值最小的边,加入生成树的边集中,顶点加入U中 217 | 以此类推,知道网络中的所有顶点都加入到生成树顶点集合U中为止 218 | 时间复杂度: 219 | 邻接矩阵:O(V^2) 220 | 邻接表:O(E+VlogV) 221 | 适用场景: 222 | 求边稠密的网的最小生成树 223 | 克鲁斯卡尔算法: 224 | 基本思想: 225 | 以边为主导,始终选择当前可用的最小权值的边 226 | 实现步骤: 227 | 设连通网络为G(V,{E}),最初先构建一个没有边的非连通图 228 | 在E中选择一个具有最小权值的边,如果该边的两个顶点落在不同的连通分量上,则将该边加入到边集中,否则舍去,重新选择一条权值次小的边 229 | 以此类推,直到所有的顶点在同一连通分量上为止 230 | 时间复杂度: 231 | O(eloge) //e是网中边的数目 232 | 适用场景: 233 | 边稀疏的网的最小生成树 234 | 235 | 最短路径: 236 | 概念: 237 | 从图中的某个顶点出发到达另外一个顶点的所经过的边的权重和最小的一条路径,称为最短路径 238 | 迪杰斯特拉算法: 239 | 特点: 240 | 使用了BFS解决带权有向图或带权无向图的“单源最短路径问题”,常用于路由算法 241 | 基本思路: 242 | 采用了一种贪心的策略,每次都查找与该点距离最近的点 243 | 实现步骤: 244 | 声明一个数组dis来保存源点到各个顶点的最短距离,以及一个用于保存已经找到了最短路径的顶点的集合T 245 | 开始时,设s的权重为0,对于顶点如果存在能直接到达的边(s,m),就把dis[m]设为该边的权,否则设为无穷大,初始时T里面只有s 246 | 然后从dis中选择最小值,那么该值就是s到该值所对应的m的最短路径,把该顶点加入T中 247 | 然后查看新加入的顶点是否可以到达其他定点,并查看通过该点到达m的路径是否比dis中的短,是的话就替换掉当前dis中的值 248 | 以此类推,直到T中包含了图中所有的顶点为止 249 | 弗洛伊德算法: 250 | 特点: 251 | 解决“任意两点间最短路径”的算法,可以正确处理有向图或无向图的最短路径问题,但是不能处理存在负权回路的图的问题 252 | 实现步骤: 253 | 假设图中有顶点N个,则需要对S和P进行N次更新。 254 | 使用弗洛伊德算法时,需要引入两个矩阵,S和P,S中的元素a[i][j]表示顶点i到顶点j的距离,P中的元素b[i][j]表示顶点i到顶点j经过了b[i][j]记录的值所表示的顶点 255 | 开始时,S中的a[i][j]的值为顶点i到顶点j的权值,如果i和j不相邻,则为无穷大,P中的b[i][j]为j的值 256 | 之后进行更新,如果“a[i][j] > a[i][0] + a[0][j]”,则更新a[i][j]为“a[i][0]+a[0][j]”,b[i][j]为“b[i][0]” 257 | 如此进行N次,更新完成 258 | -------------------------------------------------------------------------------- /精通Spring 4.x企业应用开发实战学习笔记.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/精通Spring 4.x企业应用开发实战学习笔记.zip -------------------------------------------------------------------------------- /网易春季实习.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/网易春季实习.zip -------------------------------------------------------------------------------- /美团java视频一面.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/美团java视频一面.docx -------------------------------------------------------------------------------- /蚂蚁一面面经.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/蚂蚁一面面经.docx -------------------------------------------------------------------------------- /蚂蚁金服一到五面.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/VipWangQiaoqiao/leetcode-/a192aacb11593ed3f6404e347728c7714d450fb8/蚂蚁金服一到五面.docx -------------------------------------------------------------------------------- /输入一个字符串,求出该字符串包含的字符集合(SHEIN笔试): -------------------------------------------------------------------------------- 1 | import java.util.HashSet; 2 | import java.util.Scanner; 3 | import java.util.Set; 4 | public class Main{ 5 | public static void main(String[] args){ 6 | Scanner in = new Scanner(System.in); 7 | while(in.hasNext()){ 8 | char[] c = in.next().toCharArray(); 9 | StringBuffer sb = new StringBuffer(); 10 | Set set = new HashSet(); 11 | for(int i = 0;i