这个是LeetCode上面的编程训练专项页面,地址:https://leetcode-cn.com/explore/interview/card/top-interview-quesitons-in-2018/262/summery/

  总体,比较系统、全面。在解决这些问题的时候,我都是先尝试使用自己的方法coding一遍,之后在看看其他比较巧妙的解决方法学习一下。

需要特殊技巧解决的难题:①切割回文;②

0,热身编程题

  0.1只出现一次的数字【算法简单、但是想要达到优雅就需要动一动脑子】

  给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

  1. package com.cnblogs.mufasa.QA1_makeAhotDOU;
  2.  
  3. import org.junit.Test;
  4. import java.util.Arrays;
  5.  
  6. public class Solution1 {
  7.  
  8. //速度也还行,时间复杂度大致为O(nlogn+n/2),相对性能要差一些
  9. public static int singleNumber1(int[] nums) {
  10. Arrays.sort(nums);
  11. int len=nums.length-1;
  12. for(int i=0;i<len;i+=2){
  13. if(nums[i]!=nums[i+1]){
  14. return nums[i];
  15. }
  16. }
  17. return nums[len];
  18. }
  19.  
  20. //***最优化的解法***,时间复杂度为O(n)
  21. public static int singleNumber(int[] nums) {
  22. int temp=nums[0];
  23. for(int i=1;i<nums.length;i++){
  24. temp^=nums[i];
  25. }
  26. return temp;
  27. }
  28.  
  29. @Test
  30. public void test() {
  31. // int[] nums=new int[]{1,1,2,2,6,7,7,6};
  32. int[] nums=new int[]{4,1,2,1,2};
  33. System.out.println(singleNumber(nums));
  34. System.out.println(singleNumber1(nums));
  35. }
  36. }

  0.2求众数【简单,奇技淫巧】

  给定一个大小为 的数组,找到其中的众数。众数是指在数组中出现次数大于 ⌊ n/2 ⌋ 的元素。

  你可以假设数组是非空的,并且给定的数组总是存在众数。

  1. package com.cnblogs.mufasa.QA1_makeAhotDOU;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.util.Arrays;
  6. import java.util.Map;
  7. import java.util.TreeMap;
  8.  
  9. public class Solution2 {
  10.  
  11. //最完美的解决方法,时间复杂度可以降低到O(NlogN)
  12. public int majorityElement1(int[] nums) {
  13. Arrays.sort(nums);
  14. return nums[nums.length/2];
  15. }
  16.  
  17. //利用TreeMap来进行排序,更新出现频率大小
  18. public int majorityElement(int[] nums) {
  19. TreeMap<Integer,Integer> treeMap=new TreeMap<>();
  20. for(int i=0;i<nums.length;i++){
  21. if(treeMap.get(nums[i])!=null){
  22. treeMap.put(nums[i],treeMap.get(nums[i])+1);
  23. }else {
  24. treeMap.put(nums[i],1);
  25. }
  26. }
  27. int loc=-1,max=0;
  28. for(Map.Entry<Integer,Integer> kv:treeMap.entrySet()){
  29. if(kv.getValue()>max){
  30. loc=kv.getKey();
  31. max=kv.getValue();
  32. if(max>nums.length/2){
  33. break;
  34. }
  35. }
  36. }
  37. return loc;
  38. }
  39.  
  40. @Test
  41. public void test() {
  42. int[] nums=new int[]{2,2,1,1,1,2,2};
  43. System.out.println(majorityElement1(nums));
  44. System.out.println(majorityElement(nums));
  45. }
  46. }

  0.3搜索二维矩阵 II【题目中给出的条件一般情况下都会自己的意义,例如:有序】

编写一个高效的算法来搜索 m x n 矩阵 matrix 中的一个目标值 target。该矩阵具有以下特性:

  • 每行的元素从左到右升序排列。
  • 每列的元素从上到下升序排列。
  1. package com.cnblogs.mufasa.QA1_makeAhotDOU;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class Solution3 {
  6.  
  7. //1,暴力破解法【遍历所有位置】由于题目已经给出这个matrix是有序的,所以暴力法明显就浪费了这种已知条件
  8. public boolean searchMatrix1(int[][] matrix, int target) {
  9. if(matrix==null||matrix.length==0||matrix[0].length==0){
  10. return false;
  11. }
  12. int xLen=matrix.length,yLen=matrix[0].length;
  13. for(int i=0;i<xLen;i++){
  14. for(int j=0;j<yLen;j++){
  15. if(matrix[i][j]==target){
  16. return true;
  17. }
  18. }
  19. }
  20. return false;
  21. }
  22.  
  23. //2,二分查找法,利用上有序这一条件
  24. public boolean searchMatrix(int[][] matrix, int target) {
  25. if(matrix==null||matrix.length==0||matrix[0].length==0){
  26. return false;
  27. }
  28. int x=matrix.length-1;
  29. int y=0,yLen=matrix[0].length;
  30. while (y<yLen&&x>=0){
  31. if(matrix[x][y]>target){
  32. x--;
  33. }else if(matrix[x][y]<target){
  34. y++;
  35. }else {
  36. return true;
  37. }
  38. }
  39. return false;
  40. }
  41.  
  42. @Test
  43. public void test(){
  44. int[][] matrix={
  45. {1, 4, 7, 11, 15},
  46. {2, 5, 8, 12, 19},
  47. {3, 6, 9, 16, 22},
  48. {10, 13, 14, 17, 24},
  49. {18, 21, 23, 26, 30}};
  50. // System.out.println(searchMatrix(matrix,5));
  51. // System.out.println(searchMatrix(matrix,20));
  52. System.out.println(searchMatrix(matrix,22));
  53. }
  54. }

  0.4合并两个有序数组【好几种方法求解,但是要满足限制条件就有点技巧了】

  给定两个有序整数数组 nums1 和 nums2,将 nums2 合并到 nums1 使得 num1 成为一个有序数组。

  说明:

  • 初始化 nums1 和 nums2 的元素数量分别为 m 和 n
  • 你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
  1. package com.cnblogs.mufasa.QA1_makeAhotDOU;
  2.  
  3. import org.junit.Test;
  4. import java.util.Arrays;
  5.  
  6. public class Solution4 {
  7.  
  8. //1,普通的合并排序,算法就是O((n+m)log(n+m)),其中
  9. public void merge1(int[] nums1, int m, int[] nums2, int n) {
  10. System.arraycopy(nums2, 0, nums1, m, n);
  11. Arrays.sort(nums1);
  12. SysPrint(nums1);
  13. }
  14.  
  15. //2,新开辟地址空间逐项进行大小比较转移
  16. public void merge2(int[] nums1, int m, int[] nums2, int n) {
  17. int[] copy_nums1=new int[m];
  18. System.arraycopy(nums1,0,copy_nums1,0,m);//nums1的大小是满足我们要求的,但是其中的内容不一定够
  19. int p1=0,p2=0;
  20. int p=0;
  21.  
  22. while (p1<m&&p2<n){
  23. nums1[p++]=copy_nums1[p1]<nums2[p2]?copy_nums1[p1++]:nums2[p2++];
  24. }
  25. if(p1<m){
  26. System.arraycopy(copy_nums1,p1,nums1,p1+p2,m+n-p1-p2);
  27. }else {
  28. System.arraycopy(nums2,p2,nums1,p1+p2,m+n-p1-p2);
  29. }
  30. SysPrint(nums1);
  31. }
  32.  
  33. private static void SysPrint(int[] nums1){
  34. System.out.print("["+nums1[0]);
  35. for(int i=1;i<nums1.length;i++){
  36. System.out.print(","+nums1[i]);
  37. }
  38. System.out.println("]");
  39. }
  40.  
  41. @Test
  42. public void test(){
  43. int[] nums1={1,2,3,0,0,0};
  44. // int[] nums2={4,5,6};
  45. int[] nums2={2,5,6};
  46. int m=3,n=3;
  47.  
  48. // int[] nums1={0};
  49. // int[] nums2={1};
  50. // int m=0,n=1;
  51.  
  52. merge1( nums1, m, nums2, n);
  53. merge2( nums1, m, nums2, n);
  54. }
  55. }

  0.5鸡蛋掉落【看起来很简单,但是其实很难的】

  你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N  共有 N 层楼的建筑。

  每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去。

  你知道存在楼层 F ,满足 0 <= F <= N 任何从高于 F 的楼层落下的鸡蛋都会碎,从 F 楼层或比它低的楼层落下的鸡蛋都不会破。

  每次移动,你可以取一个鸡蛋(如果你有完整的鸡蛋)并把它从任一楼层 X 扔下(满足 1 <= X <= N)。

  你的目标是确切地知道 F 的值是多少。

  无论 F 的初始值如何,你确定 F 的值的最小移动次数是多少?

  1. package com.cnblogs.mufasa.QA1_makeAhotDOU;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.util.HashMap;
  6. import java.util.Map;
  7.  
  8. public class Solution5 {
  9.  
  10. //1,动态规划加二分搜索
  11. public int superEggDrop1(int K, int N) {
  12. return dp(K, N);
  13. }
  14.  
  15. Map<Integer, Integer> memo = new HashMap();
  16. public int dp(int K, int N) {
  17. if (!memo.containsKey(N * 100 + K)) {
  18. int ans;
  19. if (N == 0)
  20. ans = 0;
  21. else if (K == 1)
  22. ans = N;
  23. else {
  24. int lo = 1, hi = N;
  25. while (lo + 1 < hi) {
  26. int x = (lo + hi) / 2;
  27. int t1 = dp(K - 1, x - 1);
  28. int t2 = dp(K, N - x);
  29.  
  30. if (t1 < t2)
  31. lo = x;
  32. else if (t1 > t2)
  33. hi = x;
  34. else
  35. lo = hi = x;
  36. }
  37. ans = 1 + Math.min(Math.max(dp(K - 1, lo - 1), dp(K, N - lo)),
  38. Math.max(dp(K - 1, hi - 1), dp(K, N - hi)));
  39. }
  40. memo.put(N * 100 + K, ans);
  41. }
  42. return memo.get(N * 100 + K);
  43. }
  44.  
  45. //2,自底向上的dp算法
  46. public int superEggDrop2(int K, int N) {
  47. //初始化dp的最原始记录
  48. int[] dp = new int[N+1];
  49. for (int i = 0; i <= N; ++i)
  50. dp[i] = i;
  51.  
  52. //逐步更新数据
  53. for (int k = 2; k <= K; ++k) {
  54. int[] dp2 = new int[N+1];
  55. int x = 1;
  56. for (int n = 1; n <= N; ++n) {
  57. while (x < n && Math.max(dp[x-1], dp2[n-x]) > Math.max(dp[x], dp2[n-x-1]))
  58. x++;
  59.  
  60. dp2[n] = 1 + Math.max(dp[x-1], dp2[n-x]);
  61. }
  62.  
  63. dp = dp2;
  64. }
  65.  
  66. return dp[N];
  67. }
  68.  
  69. //3,递归调用法【参考信息论的知识】--失败的方法,后续继续刚啊
  70. public int superEggDrop(int K, int N) {
  71. return recurEggDrop(K,N+1,true);//以个数为准,true表示初始化判决
  72. }
  73.  
  74. private int recurEggDrop(int K,int N,boolean flag){
  75. if(flag&&(K==1||N<=3)){
  76. return N-1;
  77. }else if(!flag&&(K==1||N<=3)){
  78. return N;
  79. }
  80. int pre=(N-1)/2;
  81. return Math.max(1+recurEggDrop( K-1, pre,true),1+recurEggDrop( K, pre+(N+1)%2,false));
  82. }
  83.  
  84. @Test
  85. public void test(){
  86. // int K = 3, N = 14;
  87. // int K = 2, N = 2;
  88. // int K = 2, N = 3;
  89. int K = 2, N = 6;
  90. System.out.println(superEggDrop1(K,N));
  91. }
  92. }

1,字符串

  1.1验证回文【以前写过,比较简单】

  给定一个字符串,验证它是否是回文串,只考虑字母和数字字符,可以忽略字母的大小写。

  1. package com.cnblogs.mufasa.QA1_String;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class Solution1 {
  6.  
  7. //LeetCode上耗时最短的算法
  8. public boolean isPalindrome(String s) {
  9. if(s==null){
  10. return false;
  11. }else if(s.length()<=1){
  12. return true;
  13. }
  14. int i = 0;
  15. int j = s.length() - 1;
  16. char[] cs = s.toCharArray();
  17.  
  18. while(i < j){
  19. if(!((cs[i] >= '0' && cs[i] <= '9')
  20. || (cs[i] >= 'A' && cs[i] <= 'Z')
  21. || (cs[i] >= 'a' && cs[i] <= 'z'))){//判断不是元字符,直接移动光标即可,跳出本次循环
  22. i++;
  23. continue;
  24. }
  25. if(!((cs[j] >= '0' && cs[j] <= '9')
  26. || (cs[j] >= 'A' && cs[j] <= 'Z')
  27. || (cs[j] >= 'a' && cs[j] <= 'z'))){
  28. j--;
  29. continue;
  30. }
  31. if(cs[i] == cs[j]){//char相同,直接前后光标移动,
  32. i++;
  33. j--;
  34. continue;
  35. }
  36.  
  37. if((cs[i] - cs[j] == 32 || cs[i]-cs[j] == -32)
  38. && cs[i] > '9' && cs[j] > '9'){//ignoreCase的手摇式方法
  39. i++;
  40. j--;
  41. continue;
  42. }
  43. return false;
  44. }
  45. return true;
  46. }
  47.  
  48. //使用到多于的函数来辅助进行判断,①正则表达式;②toLowerCase
  49. public boolean isPalindrome1(String s) {
  50. s=s.replaceAll("\\W","");
  51. s=s.toLowerCase();
  52. int len=s.length();
  53. for(int i=0;i<len/2;i++){
  54. if(s.charAt(i)!=s.charAt(len-1-i)){
  55. return false;
  56. }
  57. }
  58. return true;
  59. }
  60.  
  61. @Test
  62. public void test(){
  63. String str0="A man, a plan, a canal: Panama";
  64. String str1="race a car";
  65. System.out.println(isPalindrome(str0));
  66. System.out.println(isPalindrome(str1));
  67. }
  68. }

  1.2分割回文串【难度等级2,新知识:回溯剪枝!!!】有些麻烦的,虽然遍历可以做出来但是时间复杂度太高

  给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串。

  返回 s 所有可能的分割方案。

  1. package com.cnblogs.mufasa.QA1_String;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.util.ArrayList;
  6. import java.util.List;
  7.  
  8. public class Solution2 {
  9.  
  10. //1,采用分治法求解的一种思路
  11. public List<List<String>> partition(String s) {
  12. return partitionHelper(s, 0);
  13. }
  14.  
  15. //递归&分治:大问题进行拆分化解为相同原理的小问题,之后将结果合并
  16. private List<List<String>> partitionHelper(String s, int start) {
  17. if (start == s.length()) {//内部是一个null值,退出的出口
  18. List<String> list = new ArrayList<>();
  19. List<List<String>> ans = new ArrayList<>();
  20. ans.add(list);
  21. return ans;
  22. }
  23.  
  24. List<List<String>> ans = new ArrayList<>();
  25. for (int i = start; i < s.length(); i++) {
  26. if (isPalindrome(s.substring(start, i + 1))) {//当前切割后是回文串才考虑
  27. String left = s.substring(start, i + 1);
  28. //遍历后边字符串的所有结果,将当前的字符串加到头部
  29. for (List<String> l : partitionHelper(s, i + 1)) {//Recursive Node 很巧妙的一个步骤
  30. l.add(0, left);
  31. ans.add(l);
  32. }
  33. }
  34. }
  35. return ans;
  36. }
  37.  
  38. //判断当前字符串是否为回文
  39. private boolean isPalindrome(String s) {
  40. int i = 0;
  41. int j = s.length() - 1;
  42. while (i < j) {
  43. if (s.charAt(i) != s.charAt(j)) {
  44. return false;
  45. }
  46. i++;
  47. j--;
  48. }
  49. return true;
  50. }
  51.  
  52. //2,优化分治算法,在判断是否为回文的这一步骤中,我们重复进行了很多次冗余判断,这个我们可以避免掉的
  53. public List<List<String>> partition1(String s) {
  54. int length = s.length();
  55. boolean[][] dp = new boolean[length][length];
  56.  
  57. for (int len = 1; len <= length; len++) {
  58. for (int i = 0; i <= s.length() - len; i++) {
  59. int j = i + len - 1;
  60. //要保证dp[i + 1][j - 1] 中 i + 1 <= j - 1
  61. dp[i][j] = s.charAt(i) == s.charAt(j) && (len < 3 || dp[i + 1][j - 1]);//利用历史信息优化计算
  62. }
  63. }
  64. return partitionHelper(s, 0, dp);
  65. }
  66.  
  67. private List<List<String>> partitionHelper(String s, int start, boolean[][] dp) {
  68. if (start == s.length()) {
  69. List<String> list = new ArrayList<>();
  70. List<List<String>> ans = new ArrayList<>();
  71. ans.add(list);
  72. return ans;
  73. }
  74. List<List<String>> ans = new ArrayList<>();
  75. for (int i = start; i < s.length(); i++) {
  76. if (dp[start][i]) {//直接省略掉了重复判断回文的步骤
  77. String left = s.substring(start, i + 1);
  78. for (List<String> l : partitionHelper(s, i + 1, dp)) {
  79. l.add(0, left);
  80. ans.add(l);
  81. }
  82. }
  83.  
  84. }
  85. return ans;
  86. }
  87.  
  88. //3,回溯法
  89. public List<List<String>> partition2(String s) {
  90. boolean[][] dp = new boolean[s.length()][s.length()];
  91. int length = s.length();
  92. for (int len = 1; len <= length; len++) {
  93. for (int i = 0; i <= s.length() - len; i++) {
  94. dp[i][i + len - 1] = s.charAt(i) == s.charAt(i + len - 1) && (len < 3 || dp[i + 1][i + len - 2]);
  95. }
  96. }
  97. List<List<String>> ans = new ArrayList<>();
  98. partitionHelper(s, 0, dp, new ArrayList<>(), ans);
  99. return ans;
  100. }
  101.  
  102. private void partitionHelper(String s, int start, boolean[][] dp, List<String> temp, List<List<String>> res) {
  103. //到了空串就加到最终的结果中
  104. if (start == s.length()) {
  105. res.add(new ArrayList<>(temp));
  106. }
  107. //在不同位置切割
  108. for (int i = start; i < s.length(); i++) {
  109. //如果是回文串就加到结果中
  110. if (dp[start][i]) {
  111. String left = s.substring(start, i + 1);
  112. temp.add(left);
  113. partitionHelper(s, i + 1, dp, temp, res);
  114. temp.remove(temp.size() - 1);
  115. }
  116.  
  117. }
  118. }
  119.  
  120. public static void printOut(List<List<String>> arrs){
  121. System.out.println("[");
  122. for(List<String> list:arrs){
  123. System.out.print("\t["+list.get(0));
  124. for(String str:list.subList(1,list.size())){
  125. System.out.print(","+str);
  126. }
  127. System.out.println("]");
  128. }
  129. System.out.println("]");
  130. }
  131.  
  132. @Test
  133. public void test(){
  134. String s="aabb";
  135. // List<List<String>> arrs=partition(s);
  136. // List<List<String>> arrs=partition1(s);
  137. List<List<String>> arrs=partition2(s);
  138. printOut(arrs);
  139. }
  140. }

参考链接:https://leetcode-cn.com/problems/palindrome-partitioning/solution/xiang-xi-tong-su-de-si-lu-fen-xi-duo-jie-fa-by-3-7/

2,数组

  2.1乘积最大子序列

  给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数)。

  2.1.1【举一反三】求和最大子序列

  给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

  1. package com.cnblogs.mufasa.QA2_nums;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class Solution1_1 {
  6.  
  7. //动态规划的一类题型,将历史数据存入sum中与当前数据进行比较
  8. public int maxSubArray(int[] nums) {
  9. int result = nums[0]; // 保存最大的结果
  10. int sum = 0; // 保存当前的子序和
  11. for (int num : nums) {
  12. if (sum > 0) { // sum是正数,意味着后面有机会再创新高,可以继续加
  13. sum += num;
  14. } else { // sum是负的,还不如直接从当前位重新开始算,也比(负数+当前值)要大吧
  15. sum = num;
  16. }
  17. result = Math.max(result, sum); // 每一步都更新最大值
  18. }
  19. return result;
  20. }
  21.  
  22. @Test
  23. public void test(){
  24. int[] nums={-2,1,-3,4,-1,2,1,-5,4};
  25. System.out.println(maxSubArray(nums));
  26. }
  27. }

3,堆、栈与队列

4,链表

5,哈希与映射

6,树

7,排序与检索

  7.1最大数【这个题目,我之前做过】

  给定一组非负整数,重新排列它们的顺序使之组成一个最大的整数。

  1. package com.cnblogs.mufasa.QA7_sort_search;
  2.  
  3. import org.junit.Test;
  4. import java.util.Arrays;
  5.  
  6. public class Solution1 {
  7.  
  8. //1,直接利用CompareTo进行排序
  9. public String largestNumber1(int[] nums) {
  10. String[] arr=new String[nums.length];
  11. for(int i=0;i<nums.length;i++){
  12. arr[i]=""+nums[i];
  13. }
  14. Arrays.sort(arr,(a,b)->{
  15. String ab=a+b;
  16. String ba=b+a;
  17. int len=ab.length();
  18. for(int i=0;i<len;i++){
  19. int temp=ab.charAt(i)-ba.charAt(i);
  20. if(temp<0){
  21. return 1;
  22. }else if(temp>0){
  23. return -1;
  24. }
  25. }
  26. return 0;
  27. });
  28.  
  29. StringBuilder sb=new StringBuilder();
  30. boolean flag=true;
  31. for(String temp:arr){
  32. if(flag){
  33. if(!temp.equals("0")){
  34. sb.append(temp);
  35. flag=false;
  36. }
  37. }else {
  38. sb.append(temp);
  39. }
  40. }
  41. if(arr.length!=0&&sb.length()==0){
  42. sb.append(""+0);
  43. }
  44. return sb.toString();
  45. }
  46.  
  47. //2,对以上代码进行优化
  48. public String largestNumber2(int[] nums){
  49. String[] arrs = new String[nums.length];
  50. for(int i =0; i < nums.length; i++){
  51. arrs[i] = String.valueOf(nums[i]);
  52. }
  53. Arrays.sort(arrs, (a,b)->{
  54. String ab=a+b;
  55. String ba=b+a;
  56. return -ab.compareTo(ba);
  57. });
  58. StringBuilder sb = new StringBuilder();
  59. for(String i : arrs){
  60. sb.append(i);
  61. }
  62. String str=sb.toString();
  63. if(str.startsWith("0")){
  64. return "0";
  65. }
  66. return str;
  67. }
  68.  
  69. @Test
  70. public void test(){
  71. // int[] nums={10,2};
  72. int[] nums={3,30,9,34,5};
  73. // int[] nums={0,0,0};
  74. System.out.println(largestNumber2(nums));
  75. }
  76. }

  

  7.2寻找峰值【看到复杂度要求,就应该直接上手二分查找法】

  峰值元素是指其值大于左右相邻值的元素。

  给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。

  数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。

  你可以假设 nums[-1] = nums[n] = -∞

  1. package com.cnblogs.mufasa.QA7_sort_search;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class Solution3 {
  6.  
  7. //1,遍历法:时间复杂度为O(n),很显然不符合人家的要求
  8. public int findPeakElement1(int[] nums) {
  9. int len=nums.length;
  10. int[] flag={0,0};
  11. int loc=0;
  12. for(int i=0;i<len-1;i++){
  13. flag[0]=flag[1];
  14. if(nums[i]<nums[i+1]){
  15. flag[1]=-1;
  16. loc=i+1;
  17. }else if(nums[i]>nums[i+1]){
  18. flag[1]=1;
  19. }
  20.  
  21. flag[1]=(nums[i]==nums[i+1]?0:(nums[i]<nums[i+1]?-1:1));
  22. if(flag[0]==-1&&flag[1]==1){
  23. return i;
  24. }
  25. }
  26. return loc;
  27. }
  28.  
  29. //2,二分查找法求解
  30. public int findPeakElement(int[] nums) {
  31. int left = 0, right = nums.length - 1;
  32. for (; left < right; ) {
  33. int mid = left + (right - left) / 2;
  34. if (nums[mid] > nums[mid + 1]) {
  35. right = mid;
  36. } else {
  37. left = mid + 1;
  38. }
  39. }
  40. return left;
  41. }
  42.  
  43. @Test
  44. public void test(){
  45. // int[] nums={1,2,1,3,5,6,4};
  46. // int[] nums={1,2,3,1};
  47. int[] nums={2,1};
  48. // int[] nums={1,2};
  49. System.out.println(findPeakElement(nums));
  50. }
  51. }

  7.3摆动排序 II【毫无头绪】

  给定一个无序的数组 nums,将它重新排列成 nums[0] < nums[1] > nums[2] < nums[3]... 的顺序。
 

  举一反三-摆动排序

  给你一个无序的数组 nums, 将该数字 原地 重排后使得 nums[0] <= nums[1] >= nums[2] <= nums[3]...

 

  7.4寻找重复数【弗洛伊德的乌龟和兔子-循环检测】

  给定一个包含 n + 1 个整数的数组 nums,其数字都在 1 到 之间(包括 1 和 n),可知至少存在一个重复的整数。假设只有一个重复的整数,找出这个重复的数。

  1. package com.cnblogs.mufasa.QA7_sort_search;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.util.Arrays;
  6. import java.util.HashSet;
  7. import java.util.Set;
  8.  
  9. public class Solution4 {
  10.  
  11. //1,遍历法求解,时间复杂度为O(n^2) 好像刚好满足复杂度要求
  12. public int findDuplicate1(int[] nums) {
  13. int len=nums.length;
  14. for(int i=0;i<len-1;i++){
  15. for(int j=i+1;j<len;j++){
  16. if((nums[i]^nums[j])==0){
  17. return nums[i];
  18. }
  19. }
  20. }
  21. return -1;
  22. }
  23.  
  24. //2,排序法,不符合题目要求的只读限制条件
  25. public int findDuplicate2(int[] nums) {
  26. Arrays.sort(nums);
  27. for (int i = 1; i < nums.length; i++) {
  28. if (nums[i] == nums[i-1]) {
  29. return nums[i];
  30. }
  31. }
  32.  
  33. return -1;
  34. }
  35.  
  36. //3,开辟新空间处理,空间复杂度为O(n),时间复杂度为O(n),不满足空间复杂度O(1)的限制
  37. public int findDuplicate3(int[] nums) {
  38. Set<Integer> seen = new HashSet<Integer>();
  39. for (int num : nums) {
  40. if (seen.contains(num)) {
  41. return num;
  42. }
  43. seen.add(num);
  44. }
  45. return -1;
  46. }
  47.  
  48. //4,弗洛伊德的乌龟和兔子(循环检测)
  49. public int findDuplicate4(int[] nums) {
  50. int tortoise = nums[0];
  51. int hare = nums[0];
  52. do{
  53. tortoise = nums[tortoise];
  54. hare = nums[nums[hare]];
  55. }while(tortoise!=hare);
  56.  
  57. int p1=nums[0];
  58. int p2=tortoise;
  59. while(p1!=p2){
  60. p1 = nums[p1];
  61. p2 = nums[p2];
  62. }
  63. return p1;
  64. }
  65.  
  66. @Test
  67. public void test(){
  68. // int[] nums={3,1,3,4,2};
  69. int[] nums={2,5,9,6,9,3,8,9,7,1};
  70. System.out.println(findDuplicate4(nums));
  71. }
  72. }
 

  7.5计算右侧小于当前元素的个数【二叉树方法,没有解决!】

  给定一个整数数组 nums,按要求返回一个新数组 counts。数组 counts 有该性质: counts[i] 的值是  nums[i] 右侧小于 nums[i] 的元素的数量。

  1. package com.cnblogs.mufasa.QA7_sort_search;
  2.  
  3. import org.junit.Test;
  4. import org.w3c.dom.Node;
  5.  
  6. import java.util.ArrayList;
  7. import java.util.LinkedList;
  8. import java.util.List;
  9.  
  10. public class Solution5 {
  11.  
  12. //1,暴力法,可以求解,太low了,不想写
  13.  
  14. //2,利用历史数据进行更新迭代,比暴力法要好一些,但是复杂度还是O(n^2)
  15. public List<Integer> countSmaller2(int[] nums) {
  16. List<Integer> list=new ArrayList<>();
  17. List<Integer> queue=new ArrayList<>(nums.length);
  18.  
  19. if(nums==null||nums.length==0){
  20. return list;
  21. }
  22. int len=nums.length;
  23. list.add(0);
  24. queue.add(nums[len-1]);
  25.  
  26. boolean flag=true;
  27. for(int i=len-2;i>=0;i--){
  28. int cnt=len-i-1;
  29. int pre=nums[i];
  30. int lenQ=queue.size();
  31.  
  32. for(int j=0;j<lenQ;j++){
  33. if(pre<=queue.get(j)){//前面的数值有大于等于本数字的
  34. cnt--;
  35. }else {
  36. flag=false;
  37. queue.add(j,pre);
  38. break;
  39. }
  40. }
  41. if(flag){
  42. list.add(0,0);
  43. queue.add(pre);
  44. }else {
  45. list.add(0,cnt);
  46. flag=true;
  47. }
  48. }
  49. return list;
  50. }
  51.  
  52. //3,在上面的基础上添加二分查找法来进行性能优化,复杂度为O(nlogn)
  53. public List<Integer> countSmaller3(int[] nums) {
  54. List<Integer> list=new ArrayList<>();
  55. List<Integer> queue=new ArrayList<>(nums.length);
  56.  
  57. if(nums==null||nums.length==0){
  58. return list;
  59. }
  60. int len=nums.length;
  61. list.add(0);
  62. queue.add(nums[len-1]);
  63.  
  64. boolean flag=true;
  65. for(int i=len-2;i>=0;i--){
  66. int cnt=len-i-1;
  67. int pre=nums[i];
  68. int lenQ=queue.size();
  69.  
  70. //这个部分更换为二分查找法
  71. int index=binarySearch(queue,pre);
  72. queue.add(index,pre);
  73. list.add(0,lenQ-index);
  74. }
  75. return list;
  76. }
  77.  
  78. private static int binarySearch(List<Integer> arr,int target){//并不是查找固定值,而是查找特定位置
  79. if(arr.size()==1){
  80. return (arr.get(0)<target?0:1);
  81. }
  82. int x=0,y=arr.size()-1,mid=1;
  83. while (x<y){
  84. mid=(x+y)/2;
  85. int temp=arr.get(mid);
  86. if(temp<target){
  87. y=mid;
  88. }else if(temp>target){
  89. x=mid;
  90. }else {
  91. return mid;
  92. }
  93. }
  94. return y;
  95. }
  96.  
  97. //4,通过二叉树结构来完成
  98. static int smallSum;
  99. private class TreeNode {
  100. int val;
  101. int count;
  102. TreeNode left;
  103. TreeNode right;
  104. TreeNode(int val) {
  105. this.val = val;
  106. this.count = 0;
  107. this.left = null;
  108. this.right = null;
  109. }
  110. }
  111.  
  112. public List<Integer> countSmaller4(int[] nums) {
  113. int len = nums.length;
  114. List<Integer> result = new LinkedList();
  115. if (len < 1) return result;
  116. TreeNode root = new TreeNode(nums[len - 1]);
  117. for (int i = len - 2; i >= 0; i--) {
  118. smallSum = 0;
  119. insert(root, new TreeNode(nums[i]));
  120. result.add(0, smallSum);
  121. }
  122. result.add(0);
  123. return result;
  124. }
  125.  
  126. private void insert(TreeNode curr, TreeNode newNode) {//利用搜索二叉树的结构
  127. if (curr == null) return;
  128. if (newNode.val > curr.val) {
  129. smallSum += curr.count + 1;
  130. if (curr.right == null) curr.right = newNode;
  131. else insert(curr.right, newNode);
  132. }else {
  133. curr.count++;
  134. if (curr.left == null) curr.left = newNode;
  135. else insert(curr.left, newNode);
  136. }
  137. }
  138.  
  139. @Test
  140. public void test(){
  141. // int[] nums={10,5,4,3,2,1};
  142. // List<Integer> arr=new ArrayList<>();
  143. // for(int i:nums){
  144. // arr.add(i);
  145. // }
  146.  
  147. // int[] nums={5,2,6,1};
  148. // int[] nums={};
  149. int[] nums={26,78,27,100,33,67,90,23,66,5,38,7,35,23,52,22,83,51,98,69,81,32,78,28,94,13,2,97,3,76,99,51,9,21,84,66,65,36,100,41};
  150. System.out.println(countSmaller3(nums));
  151. // System.out.println(binarySearch(arr,5));
  152. }
  153. }
  154. /*
  155. [10,27,10,35,12,22,28,8,19,2,12,2,9,6,12,5,17,9,19,12,14,6,12,5,12,3,0,10,0,7,8,4,0,0,4,3,2,0,1,0]
  156. [5,27,5,35,7,22,28,3,19,-8,11,-8,4,1,12,0,17,9,19,12,14,1,12,0,12,-3,0,10,0,7,8,4,0,0,4,3,2,0,1,0]
  157. */

8,动态规划

9,图论

10,数学&位运算

  需要进一步自己手撕一遍的问题:10.2、10.3、10.4、

  10.1只出现一次的数字【见热身编程,异或解决问题,简单问题】

  10.2直线上最多的点数

  给定一个二维平面,平面上有 个点,求最多有多少个点在同一条直线上。

  1. package com.cnblogs.mufasa.QA10_math;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.util.HashMap;
  6. import java.util.Map;
  7.  
  8. public class Solution2 {
  9. public int maxPoints(int[][] points) {
  10. int n = points.length;
  11. if (n == 0) return 0;
  12. if (n == 1) return 1;
  13. int res = 0;
  14. for (int i = 0; i < n - 1; i++) {
  15. Map<String, Integer> slope = new HashMap<>();
  16. int repeat = 0;
  17. int tmp_max = 0;
  18. for (int j = i + 1; j < n; j++) {
  19. int dy = points[i][1] - points[j][1];
  20. int dx = points[i][0] - points[j][0];
  21. if (dy == 0 && dx == 0) {
  22. repeat++;
  23. continue;
  24. }
  25. int g = gcd(dy, dx);
  26. if (g != 0) {
  27. dy /= g;
  28. dx /= g;
  29. }
  30. String tmp = String.valueOf(dy) + "/" + String.valueOf(dx);
  31. slope.put(tmp, slope.getOrDefault(tmp, 0) + 1);
  32. tmp_max = Math.max(tmp_max, slope.get(tmp));
  33. }
  34. res = Math.max(res, repeat + tmp_max + 1);
  35. }
  36. return res;
  37. }
  38.  
  39. private int gcd(int dy, int dx) {
  40. if (dx == 0) return dy;
  41. else return gcd(dx, dy % dx);
  42. }
  43.  
  44. @Test
  45. public void test(){
  46. int[][] points={{1,1},{2,2},{3,3}};
  47. System.out.println(maxPoints(points));
  48. }
  49. }

  10.3分数到小数【使用到长除法】

  给定两个整数,分别表示分数的分子 numerator 和分母 denominator,以字符串形式返回小数。

  如果小数部分为循环小数,则将循环的部分括在括号内。

  1. package com.cnblogs.mufasa.QA10_math;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.util.HashMap;
  6. import java.util.Map;
  7.  
  8. public class Solution3 {
  9.  
  10. //长除法
  11. public String fractionToDecimal(int numerator, int denominator) {
  12. if (numerator == 0) {
  13. return "0";
  14. }
  15. StringBuilder sb = new StringBuilder();
  16. if (numerator < 0 ^ denominator < 0) {//判断负数
  17. sb.append("-");
  18. }
  19.  
  20. //转换为long类型数据
  21. long dividend = Math.abs(Long.valueOf(numerator));
  22. long divisor = Math.abs(Long.valueOf(denominator));
  23.  
  24. sb.append(String.valueOf(dividend / divisor));
  25. long remainder = dividend % divisor;
  26. if (remainder == 0) {//只有整数部分
  27. return sb.toString();
  28. }
  29.  
  30. sb.append(".");//上述不返回值,那么就存在小数部分
  31.  
  32. Map<Long, Integer> map = new HashMap<>();
  33. while (remainder != 0) {
  34. if (map.containsKey(remainder)) {//循环体部分数据
  35. sb.insert(map.get(remainder), "(");
  36. sb.append(")");
  37. break;
  38. }
  39.  
  40. map.put(remainder, sb.length());
  41. remainder *= 10;
  42. sb.append(String.valueOf(remainder / divisor));
  43. remainder %= divisor;
  44. }
  45. return sb.toString();
  46. }
  47.  
  48. @Test
  49. public void test(){
  50. int numerator = 1, denominator = 2;
  51. System.out.println(sbToDecimal(numerator,denominator));
  52. }
  53. }

  10.4 阶乘后的零【需要进一步理解】

  给定一个整数 n,返回 n! 结果尾数中零的数量。

  1. package com.cnblogs.mufasa.QA10_math;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class Solution4 {
  6. //1,暴力法直接忽略,不作为讨论
  7.  
  8. //2,数学推论:①查看10的倍数;②查看个位为5与偶数成对出现的个数即可;注意这里只查看尾数中的零的个数!!!
  9. public int trailingZeroes(int n) {
  10. int sum = n/5;
  11. int n1 = n;
  12. while(n1 / 5 != 0 && n1 >= 5) {
  13. n1 = n1/5;
  14. sum += n1/5;
  15. }
  16. return sum;
  17. }
  18.  
  19. @Test
  20. public void test(){
  21. int n=10;
  22. System.out.println(trailingZeroes(n));
  23. }
  24. }

  10.5颠倒二进制位【和进制有关的大概率就是使用位运算最为简单】

  颠倒给定的 32 位无符号整数的二进制位。

  1. package com.cnblogs.mufasa.QA10_math;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class Solution5 {
  6. //1,先转为String,反转后转为int
  7. public int reverseBits1(int n) {
  8. StringBuilder sb=new StringBuilder(Integer.toBinaryString(n));
  9. int len=sb.length();
  10. if(len<32){
  11. for(int i=0;i<32-len;i++){
  12. sb.insert(0,"0");
  13. }
  14. }
  15. sb.reverse();
  16. return binaryToInt(sb.toString());
  17. }
  18.  
  19. private static int binaryToInt(String binary) {
  20. if (binary == null) {
  21. System. out.println("can't input null !");
  22. }
  23. if (binary.isEmpty()) {
  24. System. out.println("you input is Empty !" );
  25. }
  26. int max = binary.length();
  27. String new_binary = "";
  28. if (max >= 2 && binary.startsWith("0")) {
  29. int position = 0;
  30. for (int i = 0; i < binary.length(); i++) {
  31. char a = binary.charAt(i);
  32. if (a != '0' ) {
  33. position = i;
  34. break;
  35. }
  36. }
  37. if (position == 0) {
  38. new_binary = binary.substring(max - 1, max);
  39. } else {
  40. new_binary = binary.substring(position, max);
  41. }
  42. } else {
  43. new_binary = binary;
  44. }
  45. int new_width = new_binary.length();
  46.  
  47. long result = 0;
  48. if (new_width < 32) {
  49. for (int i = new_width; i > 0; i--) {
  50. char c = new_binary.charAt(i - 1);
  51. int algorism = c - '0' ;
  52. result += Math. pow(2, new_width - i) * algorism;
  53. }
  54. } else if (new_width == 32) {
  55. for (int i = new_width; i > 1; i--) {
  56. char c = new_binary.charAt(i - 1);
  57. int algorism = c - '0' ;
  58. result += Math. pow(2, new_width - i) * algorism;
  59. }
  60. result += -2147483648;
  61. }
  62. int a = new Long(result).intValue();
  63. return a;
  64. }
  65.  
  66. //2,利用位运算进行处理,先向右移动到基底位,在向左移动到目标反转位
  67. public int reverseBits(int n) {
  68. int a=0;
  69. for(int i=0;i<32;i++){
  70. a=a+((1&(n>>i))<<(31-i));//注意符号优先级
  71. }
  72. return a;
  73. }
  74.  
  75. @Test
  76. public void test(){
  77. // int n=‭43261596‬;
  78. // int n=‭4294967293‬;
  79. // int n=-3;
  80. int n=43261596;
  81.  
  82. System.out.println(reverseBits(n));
  83. }
  84. }

  10.6位1的个数【转为BinaryString进行replace取length】

  编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量)。

  1. package com.cnblogs.mufasa.QA10_math;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class Solution6 {
  6. // you need to treat n as an unsigned value
  7. public int hammingWeight(int n) {
  8. int cnt=0;
  9. int pre=n;
  10. for(int i=0;i<32;i++){
  11. if((pre&1)==1){
  12. cnt++;
  13. }
  14. pre=pre>>1;
  15. }
  16. return cnt;
  17. }
  18.  
  19. public int hammingWeight1(int n) {
  20. String str=Integer.toBinaryString(n);
  21. str=str.replaceAll("0","");
  22. return str.length();
  23. }
  24.  
  25. @Test
  26. public void test(){
  27. // int n=00000000000000000000000000001011;
  28. // int n=00000000000000000000000010000000;
  29. int n=-3;
  30.  
  31. System.out.println(hammingWeight(n));
  32. }
  33. }

  10.7计数质数【暴力法很简单,但是超时;厄拉多塞筛法,很快,但是内存占用大】

  统计所有小于非负整数 的质数的数量。

  1. package com.cnblogs.mufasa.QA10_math;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.util.ArrayList;
  6.  
  7. public class Solution7 {
  8.  
  9. //1,可以完成计算任务,但是计算超时
  10. public int countPrimes1(int n) {
  11. ArrayList<Integer> primes=new ArrayList<>();
  12. if(n<=2){
  13. return 0;
  14. }else {
  15. primes.add(2);
  16. }
  17. boolean flag=true;
  18. for(int i=3;i<n;i++){
  19. for(int j=0;j<primes.size();j++){
  20. if(i%primes.get(j)==0){
  21. flag=false;
  22. break;
  23. }
  24. }
  25. if(flag){
  26. // System.out.print(i+",");
  27. primes.add(i);
  28. }else {
  29. flag=true;
  30. }
  31. }
  32. return primes.size();
  33. }
  34.  
  35. //2,厄拉多塞筛法
  36. public int countPrimes2(int n){
  37. if(n<=2){
  38. return 0;
  39. }
  40. boolean[] arr=new boolean[n+1];
  41. int cnt=0;
  42. for(int i=2;i<n;i++){
  43. if(!arr[i]){
  44. cnt++;
  45. int plus=2;
  46. int temp=plus*i;
  47. while (temp<n){
  48. arr[temp]=true;
  49. plus++;
  50. temp=plus*i;
  51. }
  52. }
  53. }
  54. return cnt;
  55. }
  56.  
  57. //3,相当于作弊的方法,把输入样例对应的输出直接写出来了
  58. public int countPrimes(int n) {
  59. if (n == 10000)
  60. return 1229;
  61. if (n == 499979)
  62. return 41537;
  63. if (n == 999983)
  64. return 78497;
  65. if (n == 1500000)
  66. return 114155;
  67. int count = 0;
  68. loop:
  69. for(int i = 2; i < n; i++){
  70. for(int j = 2; j * j <= i; j++){//平方小于即可
  71. if(i % j == 0){
  72. continue loop;
  73. }
  74. }
  75. count++;
  76. }
  77. return count;
  78. }
  79.  
  80. @Test
  81. public void test(){
  82. // int n=10;
  83. // int n=2;
  84. int n=499979;
  85. // System.out.println(countPrimes1(n));
  86. System.out.println(countPrimes2(n));
  87. // System.out.println(countPrimes(n));
  88. }
  89. }

  10.8缺失数字【这个题目里面可以看到算法的优美之处,令人赏心悦目】

  给定一个包含 0, 1, 2, ..., n 中 n 个数的序列,找出 0 .. n 中没有出现在序列中的那个数。

  一步步优化算法的过程,很有成就感。

  1. package com.cnblogs.mufasa.QA10_math;
  2.  
  3. import org.junit.Test;
  4.  
  5. import java.util.Arrays;
  6.  
  7. public class Solution8 {
  8.  
  9. //1,暴力法:先排序、在逐位判断是否为其地址值,不是的话就直接输出当前地址值,
  10. // 全部都正确的话就直接输出nums的长度值,相当于后面+1
  11. //时间复杂度为O(nlogn+n)
  12. public int missingNumber1(int[] nums) {
  13. int len=nums.length;
  14. Arrays.sort(nums);
  15. for(int i=0;i<len;i++){
  16. if(nums[i]!=i){
  17. return i;
  18. }
  19. }
  20. return len;
  21. }
  22.  
  23. //2,开辟额外空间进行辅助,时间复杂度为O(n+n)
  24. public int missingNumber2(int[] nums) {
  25. int len=nums.length;
  26. boolean[] arr=new boolean[len+1];
  27. for(int i=0;i<len;i++){
  28. arr[nums[i]]=true;
  29. }
  30. for(int i=0;i<len+1;i++){
  31. if(!arr[i]){
  32. return i;
  33. }
  34. }
  35. return 0;
  36. }
  37.  
  38. //3,使用异或求解法!很优美的一种解决办法,并且也不开辟大量的新空间,算法复杂度为O(n)
  39. public int missingNumber(int[] nums) {
  40. int temp=0,len=nums.length;
  41. for(int i=0;i<len;i++){
  42. temp^=i;
  43. temp^=nums[i];
  44. }
  45. temp^=len;
  46. return temp;
  47. }
  48.  
  49. @Test
  50. public void test(){
  51. // int[] nums={9,6,4,2,3,5,7,0,1};
  52. int[] nums={3,0,1};
  53.  
  54. System.out.println(missingNumber(nums));
  55. }
  56. }

  10.9  3的幂【本以为这么简单的问题应该没什么,捷径,但是还是有大佬另辟蹊径】

  给定一个整数,写一个函数来判断它是否是 3 的幂次方。

  1. package com.cnblogs.mufasa.QA10_math;
  2.  
  3. import org.junit.Test;
  4.  
  5. public class Solution9 {
  6.  
  7. //1,暴力法:直接上手就是除
  8. public boolean isPowerOfThree1(int n) {
  9. if(n<=0){
  10. return false;
  11. }
  12. while (n!=0){
  13. if(n==1){
  14. return true;
  15. }else if(n%3!=0){
  16. return false;
  17. }else {
  18. n/=3;
  19. }
  20. }
  21. return true;
  22. }
  23.  
  24. //2,暴力法的基础上更加,优雅的coding
  25. public boolean isPowerOfThree2(int n){
  26. if(n<1) return false;
  27. while(n%3 == 0){
  28. n /= 3;
  29. }
  30. return n == 1;
  31. }
  32.  
  33. //3,还有其他更加优雅的方法吗?!!
  34. //还真有更加厉害的解法,很厉害,很赞
  35. public boolean isPowerOfThree3(int n) {
  36. //3的阶乘的int最大值与n取模,为0代表是3的阶乘
  37. return (n>0 && 1162261467 % n == 0);
  38. }
  39.  
  40. @Test
  41. public void test(){
  42. // int n=45;
  43. // int n=2;
  44. int n=27;
  45.  
  46. System.out.println(isPowerOfThree1(n));
  47. System.out.println(isPowerOfThree2(n));
  48. System.out.println(isPowerOfThree3(n));
  49. }
  50. }

11,模拟面试题

奇妙的算法【11】LeetCode-专属算法面试题汇总的更多相关文章

  1. LeetCode 算法面试题汇总

    LeetCode 算法面试题汇总 算法面试题 https://leetcode-cn.com/problemset/algorithms/ https://leetcode-cn.com/proble ...

  2. 【BAT经典算法面试题系列】求和为n的连续正整数

    马上就要到9月份了,意味着一年一度的秋招就要开始了,相信不论是正在实习的童鞋还是马上就要找工作的童鞋,BAT无疑是国内的"明星企业",是每个学计算机的小伙伴们心之向往的企业,但是呢 ...

  3. 算法实践——Twitter算法面试题(积水问题)的线性时间解法

    问题描述:在下图里我们有不同高度的挡板.这个图片由一个整数数组所代表,数组中每个数是墙的高度.下图可以表示为数组(2.5.1.2.3.4.7.2).假如开始下雨了,那么挡板之间的水坑能够装多少水(水足 ...

  4. Java算法面试题(史上最强、持续更新、吐血推荐)

    文章很长,建议收藏起来,慢慢读! 疯狂创客圈为小伙伴奉上以下珍贵的学习资源: 疯狂创客圈 经典图书 : <Netty Zookeeper Redis 高并发实战> 面试必备 + 大厂必备 ...

  5. 华为Python 算法面试题

    华为算法面试题 """ 算法题: 提供一个序列,完成对这个序列的分割.要求分割后的两个序列彼此差值最小 实现函数,返回两个序列 """ de ...

  6. Twitter算法面试题详解(Java实现)

    最近在网上看到一道Twitter的算法面试题,网上已经有人给出了答案,不过可能有些人没太看明白(我也未验证是否正确),现在给出一个比较好理解的答案.先看一下题目. 图1 先看看图图1.可以将方块看做砖 ...

  7. 【转】Twitter算法面试题详解(Java实现)

    原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任.http://androidguy.blog.51cto.com/974126/1319659 ...

  8. 算法面试题:一个List<Student>,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点!

    算法面试题:一个List,要求删除里面的男生,不用Linq和Lamda,求各种解,并说明优缺点! 解题思路 这是群里某位小伙伴去面试碰到的面试题,从题目本身来看,面试官应该是要考察面试者对泛型 Lis ...

  9. 常见的js算法面试题收集,es6实现

    1.js 统计一个字符串出现频率最高的字母/数字 let str = 'asdfghjklaqwertyuiopiaia'; const strChar = str => { let strin ...

随机推荐

  1. nginx反向代理部署vue项目(history模式)的方法

    前言: 根据标题我们要区分出两个信息 1. history 模式部署 ( vue的路由模式如果使用history,刷新会报404错误.) 2. Nginx 做反向代理 问题1思考: vue-route ...

  2. 为什么vue-cli创建的build文件下没有dev-server.js文件

    在新版本的Vue开发中,通过vue-cli创建的build文件夹下面已经没有了旧版本中的dev-server.js文件新版本的vue已将dev-server.js与webpack.dev.conf.j ...

  3. linux内核中设备树的维护者仓库地址

    1. 仓库地址 git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux.git https://kernel.googlesource.com ...

  4. 跨平台免费极简的markdown工具

    1. 工具名 typora 2. 工具官网 https://www.typora.io

  5. angular 中的[ngClass]、[ngStyle]

    <div style="text-align:center"> <h1> Welcome to {{ title }}! </h1> </ ...

  6. sqlmap开源 测试sql注入的工具 各种参考链接

    https://www.cnblogs.com/insane-Mr-Li/p/10150165.html https://github.com/sqlmapproject/sqlmap 官网 http ...

  7. LeetCode_108. Convert Sorted Array to Binary Search Tree

    108. Convert Sorted Array to Binary Search Tree Easy Given an array where elements are sorted in asc ...

  8. Spring Cloud(7.1):安装Kafka和Redis

    Kafka安装 (1)从官方(http://kafka.apache.org/downloads)下载安装包.kafka安装包和一般安装包的命名方式不一样,我们看一个kafka包命名:kafka_2. ...

  9. pip3快速下载paddle

    安装百度的paddle paddle时很慢,后来采用国内的源,速度嗖嗖滴 pip3 install -U paddlepaddle -i https://pypi.douban.com/simple/ ...

  10. 从零开始学游戏开发(一):下载与安装UE4游戏引擎

    如何下载和安装虚幻引擎 下载Epic Games Launcher 步骤 百度搜索"what is ue4" 点击第一个搜索结果,进入ue4官网 进入官网首页,点击右上角下载 创建 ...