一些程式設計題目的解析

thomaszhou發表於2018-04-13

附上我的github倉庫,會不斷更新leetcode解題答案,提供一個思路,大家共勉

希望可以給star,鼓勵繼續更新解題思路

author: thomas

一些程式設計題目的解析

這個是leetcode上面的程式設計題目

Leetcode之javascript解題(No442/No485/No561/No566)

No442. Find All Duplicates in an Array(Medium)

題目

Given an array of integers, 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.

Find all the elements that appear twice in this array.

Could you do it without extra space and in O(n) runtime?

Example:

Input:
[4,3,2,7,8,2,3,1]

Output:
[2,3]
複製程式碼

這道題給了我們一個陣列,陣列中的數字可能出現一次或兩次,讓我們找出所有出現兩次的數字

思路

  • 這類問題的一個重要條件就是1 ≤ a[i] ≤ n (n = size of array),不然很難在O(1)空間和O(n)時間內完成。
  • 方法一:正負替換的方法
    • 這類問題的核心是就是找nums[i]和nums[nums[i] - 1]的關係,我們的做法是,對於每個nums[i],我們將其對應的nums[nums[i] - 1]取相反數(因為座標是從0開始)如果其已經是負數了,說明之前存在過,我們將其加入結果res中即可
    • 當然我們每次取值的時候是取當前的絕對值來給對應的位置取負數Math.abs(elem) - 1;
  • 方法二:遍歷陣列,用lastIndexOf方法,只要從後查詢當前值的位置和當前不同,那就是我們取的值。arr.lastIndexOf(elem) !== i)
  • 方法三(最優解):
    • nums[nums[i]-1]位置累加陣列長度n,(注意nums[i]-1有可能越界),所以我們需要對n取餘,最後要找出現兩次的數只需要看nums[i]的值是否大於2n即可,最後遍歷完nums[i]陣列為[12, 19, 18, 15, 8, 2, 11, 9],我們發現有兩個數字19和18大於2n,那麼就可以通過i+1來得到正確的結果2和3了

程式碼

// 方法一
  let arr = [4,3,2,7,8,2,3,1];
  var findDuplicates = function(arr) {
		let res = [];
		arr.forEach((elem, i) => {
		  let temp = Math.abs(elem) - 1;
		  if (arr[temp] < 0) {
		    res.push(temp + 1); // 取的負值位置+1
			}
			arr[temp] = -arr[temp]
		})
		return res;
 };
 
 // 方法三
 var findDuplicates3 = function(arr) {
    let res = [],
		len = arr.length;
    for (let i = 0; i < len; ++i) {
      arr[(arr[i] - 1) % len] += len; // 對len取餘,防止越界
    }
    for (let i = 0; i < len; ++i) {
      if (arr[i] > 2 * len) res.push(i + 1);
    }
    return res;
  };

 console.log(findDuplicates3(arr));
複製程式碼

No485:Max Consecutive Ones(Easy)

題目

Given a binary array, find the maximum number of consecutive 1s in this array.

Example 1:

Input: [1,1,0,1,1,1]
Output: 3
Explanation: The first two digits or the last three digits are consecutive 1s.
    The maximum number of consecutive 1s is 3.
複製程式碼
  • Note:

The input array will only contain 0 and 1. The length of input array is a positive integer and will not exceed 10,000

思路

這道題讓我們求最大連續1的個數,不是一道難題。我們可以遍歷一遍陣列,用一個計數器cnt來統計1的個數,方法是如果當前數字為0,那麼cnt重置為0,如果不是0,cnt自增1,然後每次更新結果res即可

程式碼

/**
 * Created by zhoubowen on 2018/4/10.
 *
 * No 485. Max Consecutive Ones
 */
let arr = [1,1,0,1,1,1];
let findMaxconsecutiveOnes = function(arr) {
  let max = 0,
    count = 0;
  arr.forEach((elem, i) => {
    if (elem === 1) {
      count += 1;
    }else {
      if (count > max) {
        max = count;
      }
      count = 0;
    }
  });
  // 單獨判斷以下最後一個結果的情況
  max = count > max ? count:max;
  return max;
};
console.log(findMaxconsecutiveOnes(arr));
複製程式碼

No561:Array Partition I(Easy)

題目

Given an array of 2n integers, your task is to group these integers into n pairs of integer, say (a1, b1), (a2, b2), ..., (an, bn) which makes sum of min(ai, bi) for all i from 1 to n as large as possible.

  • Example 1:
Input: [1,4,3,2]

Output: 4
Explanation: n is 2, and the maximum sum of pairs is 4 = min(1, 2) + min(3, 4).
複製程式碼
  • Note:

n is a positive integer, which is in the range of [1, 10000]. All the integers in the array will be in the range of [-10000, 10000].

意思是:給一個2n長度的陣列,兩兩為一組,然後取每組的最小值,最後對所有組的min值求和,問如何匹配保證這個求和的值最大

思路

就是給2n個數分組,兩兩一組,使用所有組中小的那個數加起來和最小。

既然我們兩兩分組,並且只取最小的那個值,那兩個值中較大的值就浪費了。為了使浪費最低,那就每個分組都保證大的那個值只比小的那個值大一點點(也就是最接近小的那個值)。

先將所有數排序,然後就是以排序後的值從前往後每2個值為一組(這樣就保證每個組中大的值最接近小的值),由於每個分組都是最小的值,所以我們取的值就是位置1,3,5...的值

程式碼

//
let arr = [1,4,3,2];
var arrayPariSum = function(arr) {
  let first = 1,
    end = arr.length;
  arr = QuickSort(arr, first, end); // 這是呼叫快排函式
  let len = arr.length,
    sum = 0;
  for (let i = 0; i < len; i += 2) { //只取1,3,5..位置的值相加
    sum += arr[i];
  }
  return sum;
};
console.log(arrayPariSum(arr));
複製程式碼

No566:Reshape the Matrix(Easy)

題目

題目:給一個二維陣列和兩個數字,返回一個二維陣列,第一個數字代表返回的陣列的行,第二個數字代表列。

Example 1:
Input: 
nums = 
[[1,2],
 [3,4]]
r = 1, c = 4
Output: 
[[1,2,3,4]]
Explanation:
The row-traversing of nums is [1,2,3,4]. The new reshaped matrix is a 1 * 4 matrix, fill it row by row by using the previous list.
複製程式碼

Example 2:

Input: 
nums = 
[[1,2],
 [3,4]]
r = 2, c = 4
Output: 
[[1,2],
 [3,4]]
Explanation:
There is no way to reshape a 2 * 2 matrix to a 2 * 4 matrix. So output the original matrix.
複製程式碼

思路

  • 剛開始想邏輯想不明白,可能是想迴圈一下搞定,但是不行,只能在迴圈外面建立兩個變數來控制要返回的陣列的接收:
  • javascript在多維陣列的建立上和其他語言不同,沒有多維陣列,所以只能自己不斷地在內部建立新的陣列(用到的時候,再建立)

程式碼

<script>
    let arr = [[1,2],[3,4],[5,6]];
	let r = 2, c = 3;
	let matrixReshape = function(arr, r, c) {
	  if (arr === null) {
	    return false;
	  }
	  if (arr.length * arr[0].length !== r * c) {
	    return arr;
	  }
	  let [tempr, tempc,row, col] = [0, 0, arr.length, arr[0].length],
	  res = [];
      res[tempr] = [];// 這裡要先在陣列res中建立一個新的陣列
	  for (let i = 0; i < row; i++) {
	    for (let j = 0; j < col; j++) {
	      res[tempr][tempc] = arr[i][j];
	      if (tempc === c-1) { // 第一行滿了
	        tempr += 1;
	        if (tempr < r) {
              res[tempr] = [];// 如果滿足條件,在內部多建立一個空陣列
			}
	        tempc = 0;
			continue;
		  }
		  tempc += 1;
		}
	  }
	  return res;
	}
	console.log(matrixReshape(arr, r, c))
複製程式碼

相關文章