LeetCode 刷題--數組

面試題03 數組中重複的數字

找出數組中重複的數字。

在一個長度爲 n 的數組 nums 裏的所有數字都在 0~n-1 的範圍內。數組中某些數字是重複的,但不知道有幾個數字重複了,也不知道每個數字重複了幾次。請找出數組中任意一個重複的數字。

示例 1:

輸入:
[2, 3, 1, 0, 2, 5, 3]
輸出:2 或 3

class Solution {
    public int findRepeatNumber(int[] nums) {

     int j = nums.length;
     Arrays.sort(nums);
     for(int i = 1 ; i< j ; i++){
         if(nums[i] == nums[i-1]) {
            return nums[i];

         }
     }
     return -1;
    }
}

287 尋找重複數

給定一個包含 n + 1 個整數的數組 nums,其數字都在 1 到 n 之間(包括 1 和 n),可知至少存在一個重複的整數。假設只有一個重複的整數,找出這個重複的數。

示例 1:

輸入: [1,3,4,2,2]
輸出: 2
示例 2:

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

class Solution {
    public int findDuplicate(int[] nums) {
        //給定一個8個數字的數組,數組裏數字範圍應該是【1,7】
        //1,2,3,4,5,6,7
        //2,3,5,1,2,7,6,4
        //mid指向4,看小於等於4的個數,應該是4個
        //如果大於4個,說明【1,4】之間有重複
       int l =1;
       int r = nums.length -1;//[1,7]
       while(l < r){
           int mid = l+ (r-l)/2;
           int count=0;
           for(int i = 0; i<nums.length; i++){
               if(nums[i]<= mid)  count++;
           }
           //嚴格意義上講,【1,4】區間內必需只出現4個數字
           if(count > mid ){
             r= mid;//在左邊
           }else{
             l = mid+1;
           }   
       }
       return l;//注意返回下標的值
    }
}

class Solution {
    public int findDuplicate(int[] nums) {
        Arrays.sort(nums);
        for(int i = 1; i<nums.length; i++){
            if(nums[i] == nums[i-1])  return nums[i];
        }
        return -1;
    }
}

class Solution {
    public int findDuplicate(int[] nums) {
       Set<Integer> set = new HashSet<>();
       for(int num: nums){
           if(!set.add(num)) return num;
       }
       return -1;
    }
}

面試題 56-1 數組中數字出現的次數

一個整型數組 nums 裏除兩個數字之外,其他數字都出現了兩次。請寫程序找出這兩個只出現一次的數字。要求時間複雜度是O(n),空間複雜度是O(1)。

示例 1:

輸入:nums = [4,1,4,6]
輸出:[1,6] 或 [6,1]
示例 2:

輸入:nums = [1,2,10,4,1,4,3,3]
輸出:[2,10] 或 [10,2]

class Solution {
    public int[] singleNumbers(int[] nums) {
     int arr[] = new int[10001];
     int i,j = 0;
     for(i = 0 ; i <nums.length; i++){
         arr[nums[i]]++;
     }
     for(i = 0 ; i <arr.length; i++){
         if(arr[i] == 1){
             nums[j] = i;
             j++;
         }
     }
     return new int[]{nums[0],nums[1]};
    }
}
class Solution {
    public int[] singleNumbers(int[] nums) {
     Set<Integer> set = new HashSet<>();
     for(int i = 0 ; i< nums.length; i++){
         if(set.contains(nums[i])) set.remove(nums[i]);
         else set.add(nums[i]);
     }

     return set.stream().mapToInt(Integer::intValue).toArray();
    }
//集合轉爲數組核心代碼:
//list.stream().mapToInt(Integer::intValue).toArray();
}

class Solution {
    public int[] singleNumbers(int[] nums) {
     Arrays.sort(nums);
     Stack<Integer> stack  = new Stack<>();
     for(int num : nums){
         //挨個入棧,與棧頂相同就棧頂出棧,否則入棧
         
         if(stack.isEmpty())  stack.push(num);
         else{
             if(stack.peek() != num)  stack.push(num);
             else stack.pop();
         }
     }
     int[] res = new int[2];
     res[1] = stack.pop();
     res[0] = stack.pop();
     return res;
    }
}

class Solution {
    public int[] singleNumber(int[] nums) {
        int res[] = new int[2];
        int j = 0;
    HashMap<Integer, Integer> hashmap = new HashMap<>();
    for (int num : nums)
      hashmap.put(num, hashmap.getOrDefault(num, 0) + 1);
    for (int k : hashmap.keySet())
      if (hashmap.get(k) == 1) res[j++] = k;
   
   return res;
  }
}
class Solution {
    public int findDuplicate(int[] nums) {
       Map<Integer, Integer> map = new HashMap<>();
       for(int num: nums){
          map.put(num, map.getOrDefault(num, 0)+1);
       }
       for(int k: map.keySet()){
          if(map.get(k)>1) return k;
       }
       return -1;
        
    }
}

137. 只出現一次的數字

給定一個非空整數數組,除了某個元素只出現一次以外,其餘每個元素均出現了三次。找出那個只出現了一次的元素。

說明:

你的算法應該具有線性時間複雜度。 你可以不使用額外空間來實現嗎?

示例 1:

輸入: [2,2,3,2]
輸出: 3
示例 2:

輸入: [0,1,0,1,0,1,99]
輸出: 99

class Solution {
    public int singleNumber(int[] nums) {
    HashMap<Integer, Integer> hashmap = new HashMap<>();
    for (int num : nums)
      hashmap.put(num, hashmap.getOrDefault(num, 0) + 1);
    for (int k : hashmap.keySet())
      if (hashmap.get(k) == 1) return k;
    return -1;
  }
}

面試題66. 構建乘積數組

給定一個數組 A[0,1,…,n-1],請構建一個數組 B[0,1,…,n-1],其中 B 中的元素 B[i]=A[0]×A[1]×…×A[i-1]×A[i+1]×…×A[n-1]。不能使用除法。

示例:

輸入: [1,2,3,4,5]
輸出: [120,60,40,30,24]

class Solution {
    public int[] constructArr(int[] a) {
   //除自身以外所有數組的乘積
   int[] left = new int[a.length];
   int[] right = new int[a.length];
   int[] ans = new int[a.length];
   int k = 1;
   for(int i = 0 ; i<a.length; i++){
       left[i] = k;//不乘自身
       k = k*a[i];
   }
   k=1;
   for(int i = a.length -1; i>=0 ;i--){
       right[i] = k;
       k= k*a[i];
   }
   for(int i = 0 ;i <a.length; i++){
       ans[i] = left[i]*right[i];
   }
    return ans;
    }
}

面試題04 二維數組的查找

在一個 n * m 的二維數組中,每一行都按照從左到右遞增的順序排序,每一列都按照從上到下遞增的順序排序。請完成一個函數,輸入這樣的一個二維數組和一個整數,判斷數組中是否含有該整數。

示例:

現有矩陣 matrix 如下:

[
  [1,   4,  7, 11, 15],
  [2,   5,  8, 12, 19],
  [3,   6,  9, 16, 22],
  [10, 13, 14, 17, 24],
  [18, 21, 23, 26, 30]
]
給定 target = 5,返回 true。

給定 target = 20,返回 false

此題中,需要根據矩陣的特殊性,
左下角數字:列中數字最大,行中數字最小
右上角數字:行中數字最大,列中數字最小

class Solution {
    public boolean findNumberIn2DArray(int[][] matrix, int target) {
    //二維數組查找,左下角標誌數法
    //左下角數字是一列中最大的,一行中最小的
    int i = matrix.length-1;
    int j = 0;
    while(i>=0 && j <= matrix[0].length-1){
        if(matrix[i][j] == target) return true;
        else if(matrix[i][j] < target) j++;
        else i--;
    }
    return false;

    }
}

面試題 10.01 合併排序的數組

給定兩個排序後的數組 A 和 B,其中 A 的末端有足夠的緩衝空間容納 B。 編寫一個方法,將 B 合併入 A 並排序。

初始化 A 和 B 的元素數量分別爲 m 和 n。

示例:

輸入:
A = [1,2,3,0,0,0], m = 3
B = [2,5,6], n = 3

輸出: [1,2,2,3,5,6]

class Solution {
    public void merge(int[] A, int m, int[] B, int n) {
//歸併排序,從後往前
    int startA = m-1, startB = n-1, mergeAB = m+n-1;
    int  temp = 0;
    //如果AB都沒有走完
    while(startA>=0 && startB >=0){
      if(A[startA] > B[startB]){
          A[mergeAB] = A[startA];
          mergeAB--;
          startA--;
      }else{
          A[mergeAB] = B[startB];
          mergeAB--;
          startB--;
      }
    }
    //B沒有走完
    while(startB >=0){
          A[mergeAB] = B[startB];
          mergeAB--;
          startB--;
      }
      //A沒有走完
     //不用管

    }
}

45. 把數組排成最小的數

輸入一個正整數數組,把數組裏所有數字拼接起來排成一個數,打印能拼接出的所有數字中最小的一個。

示例 1:
輸入: [10,2]
輸出: “102”

示例 2:
輸入: [3,30,34,5,9]
輸出: “3033459”

Arrays 類中的 sort 方法承諾可以對對象數組進行排序,但要求滿足下列條件:
對象所屬的類必須實現 Comparable 接口,重寫 compareTo 方法
String類型的數組可以直接調用sort函數
在Java中String和基本數據類型都默認已經實現了Comparable接口
->是lambda表達式,就是匿名函數。
最簡單的例子是 Collections.sort(list, (x, y) -> y - x); 其中
(x, y) -> y - x是一個lambda表達式,輸入兩個參數x, y,返回值 y-x。“->”起分隔作用,Java會自動翻譯。
左側:Lambda 表達式的參數列表
右側:Lambda 表達式中所需執行的功能, 即 Lambda 體

class Solution {
    public String minNumber(int[] nums) {
    //新建一個字符串數組
    String[] strNumbers  = new String[nums.length];
    
    for(int i = 0; i<nums.length; i++){
        strNumbers[i] = String.valueOf(nums[i]);
    }
    //排序
    //sort函數參數可以爲類
    Arrays.sort(strNumbers, new Comparator<String>() {
        @Override
        public int compare(String o1, String o2){
            return (o1 + o2).compareTo(o2 + o1);
            
        }
    });
    //將該字符串元素拼接起來
    StringBuilder builder = new StringBuilder();
    for(int i= 0; i<strNumbers.length; i++){
        builder.append(strNumbers[i]);
    }
    return builder.toString();

    }
    /*升序排的話就是第一個參數.compareTo(第二個參數)
   降序排的話就是第二個參數.compareTo(第一個參數)
*/
}

class Solution {
    public String minNumber(int[] nums) {
    List<String> list = new ArrayList<>();
    for(int num: nums){
        list.add(String.valueOf(num));
    }
    list.sort((o1,o2) -> (o1+o2).compareTo(o2+o1));
    //把sort函數裏面的o1,o2參數改爲o1+o2
    return String.join("",list);
    //join用於字符串拼接
    //String[] arrStr=new String[]{"a","b","c"};a-b-c
     //System.out.println(String.join("-", arrStr));
     //輸出結果是 a-b-c
    }
}

《compare(T o1, T o2)是中的o1,o2代表什麼,是怎麼實現排序的?怎麼和compareTo()配合使用?

答:o1和o2每次只取一個數據,就一次只比較兩個數據,假如比較7,8,9,5,6,那麼第一次比較o1先取8,o2取7(很奇怪,我當時以爲是順着取值,但是很奇怪,他是相鄰兩個值逆着取值,但不管他,開心就好),接下來配合compareTo()實現這兩個數的排序,o1.compareTo(o2)會返回一個int值,如果0說明o1和o2相等,如果返回負值,那麼o1和o2會倒序排序,返回正值,那麼o1和o2會正序排序。返回值之後這兩個值就進行了排序,至此,這兩個值已經排序好了,接下來第二次排序,o1取9,o2取8,第三次o1取5,o2取9…

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章