<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          十連發(fā),Leetcode算法題分享(哈希表)

          共 29786字,需瀏覽 60分鐘

           ·

          2021-03-17 20:04

          文章已收錄Github精選,歡迎Star:https://github.com/yehongzhi/learningSummary

          前言

          本篇文章主要講解leetcode上,關(guān)于哈希表(簡單難度)的算法題目。

          1. 兩數(shù)之和

          題目

          給定一個整數(shù)數(shù)組 nums 和一個整數(shù)目標值 target,請你在該數(shù)組中找出 和為目標值 的那 兩個 整數(shù),并返回它們的數(shù)組下標。

          你可以假設(shè)每種輸入只會對應(yīng)一個答案。但是,數(shù)組中同一個元素不能使用兩遍。

          你可以按任意順序返回答案。

          示例1

          輸入:nums = [2,7,11,15], target = 9
          輸出:[0,1]
          解釋:因為 nums[0] + nums[1] == 9 ,返回 [01] 。

          示例2

          輸入:nums = [3,2,4], target = 6
          輸出:[1,2]

          解法1(暴力解法)

          思路:

          因為在數(shù)組中有兩個整數(shù)的和等于目標值,很自然地我們就會想到一個個來嘗試。我們知道目標值target和nums[i],只需要找到nums[j],然后返回new int[]{i,j}即可。

          代碼如下:

          public int[] twoSum(int[] nums, int target) {
              for (int i = 0; i < nums.length; i++) {
                  //由于數(shù)組中同一個元素不能使用兩遍,所以j從i的下一個元素開始
                  for (int j = i + 1; j < nums.length; j++) {
                      if (target - nums[i] == nums[j]) {
                          return new int[]{i, j};
                      }
                  }
              }
              return new int[]{};
          }

          提交代碼,結(jié)果如下:

          按道理嵌套循環(huán)的話,時間應(yīng)該會久一點,居然僅用了0ms,我也不太相信,但是提交了三四次也是這個結(jié)果,不管了,哈哈~

          假如我們想去掉嵌套循環(huán),優(yōu)化一下,怎么做呢?沒錯,就是今天的主角,哈希表!

          解法2(HashMap)

          思路:

          創(chuàng)建一個Map集合,key是nums[i]元素的值,value是下標值i。當target - 當前遍歷的元素的差值在map中存在時,就返回new int[]{map.get(target-nums[i]),i}。如果不在map集合中,就把元素值和元素下標存進map集合中。

          代碼如下:

          public int[] twoSum(int[] nums, int target) {
              //map的key是nums[i]的值,value是下標i
              Map<Integer, Integer> map = new HashMap<>();
              for (int i = 0; i < nums.length; i++) {
                  //獲取結(jié)果值與nums[i]的差值
                  int diff = target - nums[i];
                  //如果包含的話,返回結(jié)果
                  if (map.containsKey(diff)) {
                      return new int[]{map.get(diff), i};
                  } else {
                      map.put(nums[i], i);
                  }
              }
              return new int[]{};
          }

          提交代碼,結(jié)果如下:

          349. 兩個數(shù)組的交集

          題目

          給定兩個數(shù)組,編寫一個函數(shù)來計算它們的交集。

          示例 1

          輸入:nums1 = [1,2,2,1], nums2 = [2,2]
          輸出:[2]

          實例2

          輸入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
          輸出:[9,4]

          解法1(暴力解法)

          嵌套循環(huán),比較兩個數(shù)組中的元素,如果nums1[i] == nums2[j]的話,表示兩個數(shù)組中都有的數(shù)字,則添加到HashSet(去重),最后再把HashSet轉(zhuǎn)換成數(shù)組輸出。

          代碼如下:

          public int[] intersection(int[] nums1, int[] nums2) {
              Set<Integer> set = new HashSet<>();
              for (int i = 0; i < nums1.length; i++) {
                  for (int j = 0; j < nums2.length; j++) {
                      if (nums1[i] == nums2[j]) {
                          set.add(nums1[i]);
                      }
                  }
              }
              //HashSet轉(zhuǎn)換成數(shù)組輸出
              return set.stream().mapToInt(Integer::intValue).toArray();
          }

          提交代碼,結(jié)果如下:

          經(jīng)典的擊敗5%的用戶,這是很正常的結(jié)果,因為使用了嵌套循環(huán),而且還要把HashSet轉(zhuǎn)換成數(shù)組,非常耗費性能,那么有沒有優(yōu)化空間呢,答案是肯定有的。

          解法2

          如果要判斷一個整數(shù)是否包含在無序的數(shù)組中,只能從頭遍歷到尾。既然數(shù)組在判斷時需要從頭到尾遍歷這么耗費性能,那我們能不能換一種數(shù)據(jù)結(jié)構(gòu),做到快速判斷是否包含在其中呢,答案就是哈希表。HashSet的底層就是一個哈希表,所以我們把nums1的數(shù)全部存入一個HashSet中,然后再遍歷nums2,判斷nums中的元素是否包含在HashSet中即可。

          代碼如下:

          public int[] intersection(int[] nums1, int[] nums2) {
              Set<Integer> s1 = new HashSet<>();
              for (int n1 : nums1) {
                  s1.add(n1);
              }
              Set<Integer> s2 = new HashSet<>();
              for (int n2 : nums2) {
                  if (s1.contains(n2)) {
                      s2.add(n2);
                  }
              }
              //把set集合轉(zhuǎn)成數(shù)組,返回
              int[] res = new int[s2.size()];
              int i = 0;
              for (Integer num : s2) {
                  res[i] = num;
                  i++;
              }
              return res;
          }

          提交代碼,結(jié)果如下:

          350. 兩個數(shù)組的交集II

          題目

          給定兩個數(shù)組,編寫一個函數(shù)來計算它們的交集。

          示例1

          輸入:nums1 = [1,2,2,1], nums2 = [2,2]
          輸出:[2,2]

          示例2

          輸入:nums1 = [4,9,5], nums2 = [9,4,9,8,4]
          輸出:[4,9]

          說明

          • 輸出結(jié)果中每個元素出現(xiàn)的次數(shù),應(yīng)與元素在兩個數(shù)組中出現(xiàn)次數(shù)的最小值一致。
          • 我們可以不考慮輸出結(jié)果的順序。

          解法1

          這道題是上面那道題的變形,不同在于輸出結(jié)果不需要去重。因此我們不能使用HashSet存儲,而要改用HashMap,key是數(shù)組中的元素,value是元素的個數(shù)。在判斷是否包含在其中的時候,還要判斷個數(shù)是否大于0,每添加一個元素到結(jié)果集中就從HashMap中減去一個元素的個數(shù)。

          最后把結(jié)果集轉(zhuǎn)成數(shù)組返回即可。

          代碼如下:

          public int[] intersect(int[] nums1, int[] nums2) {
              //key為num1的元素,value為元素出現(xiàn)的次數(shù)
              Map<Integer, Integer> map = new HashMap<>();
              for (int num : nums1) {
                  map.put(num, map.getOrDefault(num, 0) + 1);
              }
              List<Integer> list = new ArrayList<>();
              for (int num : nums2) {
                  if (map.containsKey(num) && map.get(num) > 0) {
                      list.add(num);
                      map.put(num, map.get(num) - 1);
                  }
              }
              int[] res = new int[list.size()];
              for (int i = 0; i < list.size(); i++) {
                  res[i] = list.get(i);
              }
              return res;
          }

          提交代碼,結(jié)果如下:

          771. 寶石與石頭

          題目

          給定字符串J 代表石頭中寶石的類型,和字符串 S代表你擁有的石頭。S 中每個字符代表了一種你擁有的石頭的類型,你想知道你擁有的石頭中有多少是寶石。

          J 中的字母不重復(fù),J 和 S中的所有字符都是字母。字母區(qū)分大小寫,因此"a"和"A"是不同類型的石頭。

          示例1

          輸入: J = "aA", S = "aAAbbbb"
          輸出: 3

          示例2

          輸入: J = "z", S = "ZZ"
          輸出: 0

          注意:

          • SJ 最多含有50個字母。
          • J 中的字符不重復(fù)。

          解法1(HashSet)

          這也是一個很典型的使用哈希表判斷是否包含在集合中的題目。思路還是跟前面判斷交集的一樣,先把其中一個字符串遍歷每個字符,放進HashSet,然后再遍歷另一個字符串,判斷是否包含在其中,包含則數(shù)量加一。最后返回結(jié)果。

          代碼如下:

          public int numJewelsInStones(String jewels, String stones) {
              Set<Character> set = new HashSet<>();
              for (char j : jewels.toCharArray()) {
                  set.add(j);
              }
              int count = 0;
              for (char s : stones.toCharArray()) {
                  if(set.contains(s)){
                      count++;
                  }
              }
              return count;
          }

          提交代碼,結(jié)果如下:

          解法2(簡化版哈希表)

          上面的解法執(zhí)行用時2ms已經(jīng)很快了,但是如果細心想一下,其實沒必要使用HashSet集合,因為題目已經(jīng)告訴我們只有字母,因此我們大可以使用一個數(shù)組模擬一個哈希表,優(yōu)化一下。

          代碼如下:

          public int numJewelsInStones(String jewels, String stones) {
              //大寫字母'A'的ASCII碼是65,小寫字母'z'的ASCII碼是122
              //所以使用一個長度58的數(shù)組已經(jīng)足夠
              boolean[] bools = new boolean[58];
              for (char j : jewels.toCharArray()) {
                  //類似哈希映射,把對應(yīng)下標標記為true
                  bools[j - 'A'] = true;
              }
              int count = 0;
              for (char s : stones.toCharArray()) {
                  boolean bool = bools[s - 'A'];
                  //如果對應(yīng)下標為true,則是寶石
                  if (bool) {
                      count++;
                  }
              }
              return count;
          }

          提交代碼,結(jié)果如下:

          387. 字符串中的第一個唯一字符

          題目

          給定一個字符串,找到它的第一個不重復(fù)的字符,并返回它的索引。如果不存在,則返回 -1。

          示例

          s = "leetcode"
          返回 0

          s = "loveleetcode"
          返回 2

          **提示:**你可以假定該字符串只包含小寫字母。

          解法1(HashMap)

          我們可以遍歷兩次,第一次遍歷使用HashMap記錄字符出現(xiàn)的次數(shù),第二次遍歷找出只出現(xiàn)一次的字符,返回它的索引。

          代碼如下:

          public int firstUniqChar(String s) {
              Map<Character, Integer> map = new HashMap<>();
              char[] chars = s.toCharArray();
              for (char c : chars) {
                  map.put(c, map.getOrDefault(c, 0) + 1);
              }
              for (int i = 0; i < chars.length; i++) {
                  Integer count = map.get(chars[i]);
                  if (count == 1) {
                      return i;
                  }
              }
              return -1;
          }

          提交代碼,結(jié)果如下:

          解法2

          顯然解法1耗時過長,不是很理想。怎么優(yōu)化呢,要抓住題目給的提示,只包含小寫字母。既然只含有小寫字母,那么我們就可以簡化哈希表,使用一個數(shù)組代替。

          代碼如下:

          public int firstUniqChar(String s) {
              int[] hash = new int[26];
              char[] chars = s.toCharArray();
              for (char ch : chars) {
                  hash[ch - 'a']++;
              }
              for (int i = 0; i < chars.length; i++) {
                  if (hash[chars[i] - 'a'] == 1) {
                      return i;
                  }
              }
              return -1;
          }

          提交代碼,結(jié)果如下:

          1365. 有多少小于當前數(shù)字的數(shù)字

          給你一個數(shù)組 nums,對于其中每個元素 nums[i],請你統(tǒng)計數(shù)組中比它小的所有數(shù)字的數(shù)目。

          換而言之,對于每個 nums[i] 你必須計算出有效的 j 的數(shù)量,其中 j 滿足 j != i 且 nums[j] < nums[i] 。

          以數(shù)組形式返回答案。

          示例1

          輸入:nums = [8,1,2,2,3]
          輸出:[4,0,1,1,3]
          解釋: 
          對于 nums[0]=8 存在四個比它小的數(shù)字:(12,2 和 3)。 
          對于 nums[1]=1 不存在比它小的數(shù)字。
          對于 nums[2]=2 存在一個比它小的數(shù)字:(1)。 
          對于 nums[3]=2 存在一個比它小的數(shù)字:(1)。 
          對于 nums[4]=3 存在三個比它小的數(shù)字:(12 和 2)。

          示例2

          輸入:nums = [6,5,4,8]
          輸出:[2,1,0,3]

          示例3

          輸入:nums = [7,7,7,7]
          輸出:[0,0,0,0]

          提示:

          • 2 <= nums.length <= 500
          • 0 <= nums[i] <= 100

          解法1(暴力法)

          暴力法思路很簡單粗暴,就是拿每一個元素跟數(shù)組中除了自身之外的每一個元素對比,只要元素大于數(shù)組中其他的數(shù)就計數(shù)加一,最后把計數(shù)收集起來就是結(jié)果。

          代碼如下:

          public int[] smallerNumbersThanCurrent(int[] nums) {
              int[] res = new int[nums.length];
              int count = 0;
              for (int i = 0; i < nums.length; i++) {
                  int num = nums[i];
                  for (int j = 0; j < nums.length; j++) {
                      //排除跟自己對比
                      if (i == j) {
                          continue;
                      }
                      //如果元素本身比其他數(shù)要大,計數(shù)+1
                      if (num > nums[j]) {
                          count++;
                      }
                  }
                  //收集計數(shù)
                  res[i] = count;
                  //計數(shù)器歸0
                  count = 0;
              }
              return res;
          }

          提交代碼,結(jié)果如下:

          解法2

          明顯解法1使用了嵌套循環(huán),導(dǎo)致耗時太多,結(jié)果不太理想。優(yōu)化代碼前,我們可以先看看提示0 <= nums[i] <= 100,也就是說元素的值在0到100范圍內(nèi)。我們可以使用一個101長度的數(shù)組統(tǒng)計元素出現(xiàn)的次數(shù),當我們要計算有多少少于該元素的數(shù)字時,就只需要該元素前面所有元素出現(xiàn)的次數(shù)即可。

          代碼如下:

          public int[] smallerNumbersThanCurrent(int[] nums) {
              int[] hash = new int[101];
              //使用數(shù)組統(tǒng)計數(shù)字出現(xiàn)的次數(shù)
              for (int num : nums) {
                  //元素值相當于下標,類似于哈希映射
                  hash[num]++;
              }
              int[] res = new int[nums.length];
              for (int i = 0; i < nums.length; i++) {
                  //計數(shù)
                  int count = 0;
                  //統(tǒng)計在該元素前的所有元素(也就是小于該元素的數(shù)字)出現(xiàn)的次數(shù)
                  for (int j = nums[i] - 1; j >= 0; j--) {
                      //計數(shù)器累加,j就是統(tǒng)計哈希表的下標
                      count += hash[j];
                  }
                  res[i] = count;
              }
              return res;
          }

          提交代碼,結(jié)果如下:

          389. 找不同

          題目:

          給定兩個字符串 st,它們只包含小寫字母。

          字符串 t 由字符串 s 隨機重排,然后在隨機位置添加一個字母。

          請找出在 t 中被添加的字母。

          示例1

          輸入:s = "abcd", t = "abcde"
          輸出:"e"
          解釋:'e' 是那個被添加的字母。

          示例2

          輸入:s = "", t = "y"
          輸出:"y"

          示例3

          輸入:s = "a", t = "aa"
          輸出:"a"

          提示:

          • 0 <= s.length <= 1000
          • t.length == s.length + 1
          • st 只包含小寫字母

          解法1(HashMap)

          使用HashMap記錄字符串s中每一個字符出現(xiàn)的次數(shù),然后遍歷字符串t,通過字符獲取字符出現(xiàn)的次數(shù),次數(shù)大于0就減一,次數(shù)等于0則表示是添加的字母,返回該字母。

          代碼如下:

          public char findTheDifference(String s, String t) {
              Map<Character, Integer> map = new HashMap<>();
              for (char c : s.toCharArray()) {
                  map.put(c, map.getOrDefault(c, 0) + 1);
              }
              for (char c : t.toCharArray()) {
                  Integer count = map.getOrDefault(c, 0);
                  if (count > 0) {
                      map.put(c, count - 1);
                  } else {
                      return c;
                  }
              }
              return ' ';
          }

          提交代碼,結(jié)果如下:

          解法2

          關(guān)鍵是抓住提示,字符串s和t只包含小寫字母,所以我們還是可以使用數(shù)組簡化HashMap。小寫字母只有26個,所以我們創(chuàng)建一個26長度的int數(shù)組,統(tǒng)計s字符串中字符出現(xiàn)的次數(shù)。其他邏輯和解法1一樣即可。

          代碼如下:

          public char findTheDifference(String s, String t) {
              int[] hash = new int[26];
              for (char c : s.toCharArray()) {
                  hash[c - 'a']++;
              }
              for (char c : t.toCharArray()) {
                  if (hash[c - 'a'] > 0) {
                      hash[c - 'a']--;
                  } else {
                      return c;
                  }
              }
              return ' ';
          }

          提交代碼,結(jié)果如下:

          解法3(排序法)

          把兩個字符串轉(zhuǎn)成字符數(shù)組,然后對兩個數(shù)組排序。對排序好的數(shù)組進行遍歷對比,只要出現(xiàn)不相等的字符,就是要返回的字符。

          代碼如下:

          public char findTheDifference(String s, String t) {
              char[] sChars = s.toCharArray();
              char[] tChars = t.toCharArray();
              Arrays.sort(sChars);
              Arrays.sort(tChars);
              int length = Math.min(sChars.length, tChars.length);
              int i = 0;
              while (i < length) {
                  char sChar = sChars[i];
                  char tChar = tChars[i];
                  if (sChar != tChar) {
                      return tChar;
                  }
                  i++;
              }
              return tChars[tChars.length - 1];
          }

          提交代碼,結(jié)果如下:

          效率雖然沒有哈希表快,但是也是一種不錯的解題思路。

          217. 存在重復(fù)元素

          題目

          給定一個整數(shù)數(shù)組,判斷是否存在重復(fù)元素。

          如果存在一值在數(shù)組中出現(xiàn)至少兩次,函數(shù)返回 true 。如果數(shù)組中每個元素都不相同,則返回 false 。

          示例1

          輸入: [1,2,3,1]
          輸出: true

          示例2

          輸入: [1,2,3,4]
          輸出: false

          示例3

          輸入: [1,1,1,3,3,4,3,2,4,2]
          輸出: true

          解法1

          假如使用嵌套循環(huán),是會超出時間限制的,所以不能考慮用暴力法。一般來說,判斷一個元素是否包含在其中肯定是HashSet最快,所以我們可以用HashSet容納元素,然后判斷一下是否包含,包含則返回true,不包含則繼續(xù)裝入,如果遍歷結(jié)束都沒有返回true,則返回false。

          代碼如下:

          public boolean containsDuplicate(int[] nums) {
              Set<Integer> set = new HashSet<>();
              for (int num : nums) {
                  if (!set.contains(num)) {
                      set.add(num);
                  } else {
                      return true;
                  }
              }
              return false;
          }

          提交代碼,結(jié)果如下:

          解法2

          其實HashSet本身就有去重的效果,我們把所有的元素裝入到HashSet中,如果有重復(fù)的元素則長度和原來的長度不相等。

          代碼如下:

          public boolean containsDuplicate(int[] nums) {
              Set<Integer> set = new HashSet<>();
              for (int num : nums) {
                  set.add(num);
              }
              return set.size() != nums.length;
          }

          提交代碼,結(jié)果如下:

          409. 最長回文串

          題目

          給定一個包含大寫字母和小寫字母的字符串,找到通過這些字母構(gòu)造成的最長的回文串。

          在構(gòu)造過程中,請注意區(qū)分大小寫。比如 "Aa" 不能當做一個回文字符串。

          注意: 假設(shè)字符串的長度不會超過 1010。

          示例1

          輸入:
          "abccccdd"

          輸出:
          7

          解釋:
          我們可以構(gòu)造的最長的回文串是"dccaccd", 它的長度是 7

          解法1

          回文字符串就是從左往右讀和從右往左讀都是一樣的字符串,也就是左右對稱的字符串。要做到左右對稱,其實很簡單,只要是偶數(shù)個相同的字符就可以,比如有兩個"a",左右兩端各放一個就對稱了。

          所以我們用一個HashMap來統(tǒng)計字符出現(xiàn)的次數(shù),然后遍歷,判斷如果是偶數(shù)就累加字母出現(xiàn)的次數(shù),如果是奇數(shù)就減一讓他變成偶數(shù)再累加,最后就得到答案res,但是還沒大功告成,因為中點插進一個字母,他還是對稱的,所以最后要判斷一下累加的長度是否等于原來的字符串長度,再決定要不要再加上一個字母的長度。

          代碼如下:

          public int longestPalindrome(String s) {
              HashMap<Character, Integer> map = new HashMap<>();
              //統(tǒng)計字符出現(xiàn)的次數(shù)
              for (char c : s.toCharArray()) {
                  map.put(c, map.getOrDefault(c, 0) + 1);
              }
              int res = 0;
              for (Character key : map.keySet()) {
                  Integer val = map.get(key);
                  //如果是奇數(shù)次,減一成為偶數(shù),再累加
                  if (val % 2 != 0) {
                      res += (val - 1);
                  } else {
                      //如果是偶數(shù)次,直接累加
                      res += val;
                  }
              }
              int length = s.length();
              return res == length ? length : (res + 1);
          }

          提交代碼,結(jié)果如下:

          解法2(優(yōu)化)

          題目說明是包含大寫字母和小寫字母,所以我們還是可以使用數(shù)組來代替HashMap,以此提高代碼的執(zhí)行效率。我們只需要一個長度為128的數(shù)組來統(tǒng)計字符出現(xiàn)的次數(shù),代替HashMap。其他邏輯不變即可。

          代碼如下:

          public int longestPalindrome(String s) {
              int[] hash = new int[128];
              for (char c : s.toCharArray()) {
                  hash[c - 'A']++;
              }
              int res = 0;
              for (int count : hash) {
                  if (count % 2 != 0) {
                      res += (count - 1);
                  } else {
                      res += count;
                  }
              }
              int length = s.length();
              return res == length ? length : (res + 1);
          }

          提交代碼,結(jié)果如下:

          204. 計數(shù)質(zhì)數(shù)

          統(tǒng)計所有小于非負整數(shù) n 的質(zhì)數(shù)的數(shù)量。

          示例1

          輸入:n = 10
          輸出:4
          解釋:小于 10 的質(zhì)數(shù)一共有 4 個, 它們是 2357 。

          示例2

          輸入:n = 0
          輸出:0

          示例3

          輸入:n = 1
          輸出:0

          解法1(暴力法)

          其實這是一個很經(jīng)典的數(shù)學問題,比如要判斷223是不是質(zhì)數(shù),最粗暴的方法就是,223對(2到222)進行取余,每次取余的余數(shù)都不為0,那就是質(zhì)數(shù)。但是如果n的值非常大,那就會超過時間限制。

          代碼如下:

          public int countPrimes(int n) {
              int count = 0;
              for (int i = 0; i < n; i++) {
                  //判斷是否是質(zhì)數(shù),是質(zhì)數(shù)則計數(shù)+1
                  if (isPrimes(i)) {
                      count++;
                  }
              }
              return count;
          }

          //判斷一個數(shù)是否是質(zhì)數(shù)
          private boolean isPrimes(int num) {
              if (num <= 1) {
                  return false;
              }
              if (num == 2) {
                  return true;
              }
              //循環(huán)取余,只要有一次返回余數(shù)為0則是非質(zhì)數(shù)
              for (int i = 2; i < num; i++) {
                  if (num % i == 0) {
                      return false;
                  }
              }
              //如果余數(shù)都不為0則是質(zhì)數(shù)
              return true;
          }

          提交代碼,結(jié)果如下:

          解法2

          不如反向思維一下,我們使用一個boolean[]數(shù)組記錄每個數(shù)是否是質(zhì)數(shù),然后從2開始找出非質(zhì)數(shù)都標記成true,標記完成之后就可以統(tǒng)計質(zhì)數(shù)的數(shù)量是多少了。

          public int countPrimes(int n) {
              boolean[] booleans = new boolean[n];
              for (int i = 2; i < n; i++) {
                  for (int j = 2; j * i < n; j++) {
                      booleans[i * j] = true;
                  }
              }
              int count = 0;
              //從2開始統(tǒng)計
              for (int i = 2; i < booleans.length; i++) {
                  if (!booleans[i]) {
                      count++;
                  }
              }
              return count;
          }

          提交代碼,結(jié)果如下:

          其實上面的代碼還可以優(yōu)化一下,不需要遍歷兩次,把統(tǒng)計和標記放在一個循環(huán)即可。代碼如下:

          public int countPrimes(int n) {
              int count = 0;
              boolean[] booleans = new boolean[n];
              for (int i = 2; i < n; i++) {
                  if (!booleans[i]) {
                      for (int j = 2; j * i < n; j++) {
                          booleans[i * j] = true;
                      }
                      count++;
                  }
              }
              return count;
          }

          提交代碼,結(jié)果如下:

          解法3

          萬萬沒想到,這個題目還有0ms的題解!這是我在提交記錄中一不留神看到的,截圖給大伙看看。

          然后我點開代碼一看,好家伙,震驚我一整年!

          public int countPrimes(int n) {
              switch (n) {
                  case 0return 0;
                  case 1return 0;
                  case 2return 0;
                  case 3return 1;
                  case 4return 2;
                  case 5return 2;
                  case 6return 3;
                  case 7return 3;
                  case 8return 4;
                  case 9return 4;
                  case 10return 4;
                  case 11return 4;
                  case 12return 5;
                  case 13return 5;
                  case 14return 6;
                  case 15return 6;
                  case 10000return 1229;
                  case 499979return 41537;
                  case 999983return 78497;
                  case 1500000return 114155;
                  case 5000000return 348513;
                  defaultreturn -1;
              }
          }

          我當然不相信這是能通過的啦,于是復(fù)制了這段代碼提交試試,沒想到還真行呀!

          總結(jié)

          哈希表的算法題中有很多問題其實在實際項目中也會遇到,比如找出兩個集合的交集,找出集合中重復(fù)的元素等等,所以做一做算法題對我們的編碼能力會有很大的提升。

          這篇文章講到這里了,感謝大家的閱讀,希望看完這篇文章能有所收獲!

          覺得有用就點個贊吧,你的點贊是我創(chuàng)作的最大動力~

          我是一個努力讓大家記住的程序員。我們下期再見!?。?/strong>

          能力有限,如果有什么錯誤或者不當之處,請大家批評指正,一起學習交流!

          瀏覽 109
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  手机在线日本A V电影 | 蜜桃在线视频人妻 | 亚洲www | 全国操逼 | 国庄三级HD中文久久精品 |