兩數之和git
兩數組的交數組
移動零spa
將一個數組中的 0
移動到數組的最後面,非零元素保持原數組的順序。必須在原數組上操做。指針
public void moveZeroes(int[] nums) { if(nums==null || nums.length==0){ return; } int insertPos = 0; for(int i=0; i<nums.length; i++){ if(nums[i]!=0){ nums[insertPos++] = nums[i]; } } while(insertPos<nums.length){ nums[insertPos++] = 0; } }
樣例:nums1 = [1, 2, 2, 1]
, nums2 = [2, 2]
, 返回 [2]
.blog
解答一:用兩個HashSet排序
public int[] intersection(int[] nums1, int[] nums2) { Set<Integer> set = new HashSet<Integer>(); Set<Integer> inter = new HashSet<>(); for(int i=0; i<nums1.length; i++){ set.add(nums1[i]); } for(int j=0; j<nums2.length; j++){ if(set.contains(nums2[j])){ inter.add(nums2[j]); } } int[] rst = new int[inter.size()]; int k = 0; for(Integer s: inter){ rst[k++] = s; } return rst; }
解答二:對兩個數組排序,而後各用一個指針遍歷。three
public int[] intersection(int[] nums1, int[] nums2) { Set<Integer> set = new HashSet<Integer>(); Arrays.sort(nums1); Arrays.sort(nums2); int i=0, j=0; while(i<nums1.length && j<nums2.length){ if(nums1[i]<nums2[j]){ i++; }else if(nums1[i]>nums2[j]){ j++; }else{ set.add(nums1[i]); i++; j++; } } int[] arr = new int[set.size()]; int k = 0; for(Integer s: set){ arr[k++] = s; } return arr; }
解答三:利用HashMap
public int[] intersection(int[] nums1, int[] nums2){ Map<Integer, Integer> map = new HashMap<>(); for(int i = 0; i < nums1.length; ++i){ if(!map.containsKey(nums1[i])){ map.put(nums1[i], 1); } } List<Integer> list = new ArrayList<>(); for(int i = 0; i < nums2.length; ++i){ if(map.containsKey(nums2[i])){ list.add(nums2[i]); map.remove(nums2[i]); } } int[] res = new int[list.size()]; int k = 0; for(Integer num : list){ res[k++] = num; } return res; }
解答四:對num2排序,而後遍歷num1中的數,在num2中進行二分查找,找到就放入set中。
給一個整數數組,找到兩個數使得他們的和等於一個給定的數 target。
public int[] twoSum(int[] numbers, int target) { HashMap<Integer, Integer> hash = new HashMap<>(); int[] result = new int[2]; for(int i=0; i<numbers.length; i++){ if(hash.get(numbers[i]) == null){ hash.put(target-numbers[i], i); }else{ result[0] = hash.get(numbers[i]) +1; result[1] = i + 1; } } return result; }
給定一個旋轉排序數組,在原地恢復其排序。
public void recoverRotatedSortedArray(ArrayList<Integer> nums) { for(int i=0; i<nums.size()-1; i++){ if(nums.get(i)>nums.get(i+1)){ recover(nums, 0, i); recover(nums, i+1, nums.size()-1); recover(nums, 0, nums.size()-1); } } } private void recover(ArrayList<Integer> nums, int left, int right){ while(left<right){ int tmp = nums.get(left); nums.set(left, nums.get(right)); nums.set(right, tmp); left++; right--; } }
給定一個整數數組,找到一個具備最大和的子數組,返回其最大和。
解答一:暴力
public int maxSubArray(int[] nums) { if (nums == null || nums.length == 0) { return 0; } int maxSum = Integer.MIN_VALUE; for(int i=0; i<nums.length; i++){ int sum = 0; for(int j=i; j<nums.length; j++){ sum += nums[j]; maxSum = Math.max(maxSum, sum); } } return maxSum; }
解答二:動態規劃。遍歷,一個變量保存到當前位置時的最大值,另外一個變量保存全局最大值。
public int maxSubArray(int[] nums) { int maxEndingHere = nums[0]; // 當前位置的最大值 int max = nums[0]; // 全局最大值 for(int i=1; i<nums.length; i++){ maxEndingHere = Math.max(nums[i], maxEndingHere+nums[i]); max = Math.max(max, maxEndingHere); } return max; }
解答三:貪婪算法。遍歷,對全部數從左到右累加,同時判斷選擇最大和,若是當前sum爲負,則再加下一個數時,把sum替換爲0。
public int maxSubArray(int[] nums){ int max = Integer.MIN_VALUE; int sum = 0; for(int i=0; i<nums.length; i++){ sum += nums[i]; max = Math.max(max, sum); sum = Math.max(0, sum); //若是sum出現負,就不用在此sum爲負的基礎上再加下一個數。把sum改爲0 } return max; }
給定一個非負數,表示一個數字數組,在該數的基礎上+1,返回一個新的數組。
樣例:給定 [1,2,3]
表示 123, 返回 [1,2,4]
. 給定 [9,9,9]
表示 999, 返回 [1,0,0,0]
.
public int[] plusOne(int[] digits) { int carries = 1; for(int i=digits.length-1; i>=0 && carries>0; i--){ int sum = digits[i] + carries; digits[i] = sum % 10; carries = sum/10; } if(carries==0){ return digits; } int[] rst = new int[digits.length+1]; rst[0] = 1; for(int j=0; j<digits.length; j++){ rst[j+1] = digits[j]; } return rst; }
給定一個數組和一個值,在原地刪除與值相同的數字,返回新數組的長度。
解答:用左右兩個指針,left的值爲val時,把right賦給left,right--
public int removeElement(int[] nums, int val) { int left = 0; int right = nums.length-1; while(left<=right){ if(nums[left]==val){ nums[left] = nums[right]; right--; }else{ left++; } } return right+1; }
假設有一個數組,它的第i個元素是一支給定的股票在第i天的價格。若是你最多隻容許完成一次交易(例如,一次買賣股票),設計一個算法來找出最大利潤。
樣例:給出一個數組樣例 [3,2,3,1,2], 返回 1
解答:遍歷數組,每次都更新最大利潤和最小值。
public int maxProfit(int[] prices) { if(prices==null || prices.length==0){ return 0; } int min = prices[0]; int maxpro = 0; for(int i=1; i<prices.length; i++){ maxpro = Math.max(maxpro, prices[i]-min); min = Math.min(min, prices[i]); } return maxpro; }
給定一個排序數組,在原數組中刪除重複出現的數字,使得每一個元素只出現一次,而且返回新的數組的長度。
解答:兩個指針。i從頭至尾遍歷數組,遇到不一樣的,把值賦給count
public int removeDuplicates(int[] nums) { int count = 1; for(int i=1; i<nums.length; i++){ if(nums[i]!=nums[count-1]){ nums[count++] = nums[i]; } } return count; }
(一)兩個數組A,B。A中個數爲m,B中個數爲n。假設A有足夠的容量,把B合併到A中,成爲一個有序數組。
public void merge(int[] A, int m, int[] B, int n){ int i = m-1; int j = n-1; int k = m+n-1; while(i>=0 && j>=0){ if(A[i] > B[j]){ A[k--] = A[i--]; }else{ A[k--] = B[j--]; } } while(i>=0){ A[k--] = A[i--]; } while(j>=0){ A[k--] = B[j--]; } }
(二)合併兩個排序的整數數組A和B變成一個新的數組。
public int[] mergeSortedArray(int[] A, int[] B) { int lena = A.length; int lenb = B.length; int[] rst = new int[lena+lenb]; int i=0, j=0, k=0; while(i<lena && j<lenb){ if(A[i]<=B[j]){ rst[k++] = A[i++]; }else{ rst[k++] = B[j++]; } } while(i<lena){ rst[k++] = A[i++]; } while(j<lenb){ rst[k++] = B[j++]; } return rst; }
給出一個有n個整數的數組S,在S中找到三個整數a, b, c,找到全部使得a + b + c = 0的三元組。
解答:先把數組排序。用三個指針,i從頭至尾遍歷,left=i+1,right=length-1。把這三個數相加,結果小於0則i++,大於0則j--。
public ArrayList<ArrayList<Integer>> threeSum(int[] numbers) { ArrayList<ArrayList<Integer>> list = new ArrayList<>(); if(numbers==null || numbers.length<3){ return list; } Arrays.sort(numbers); for(int i=0; i<numbers.length-2; i++){ int left = i+1; int right = numbers.length-1; while(left<right){ int sum = numbers[i] + numbers[left] + numbers[right]; if(sum==0){ ArrayList<Integer> tmp = new ArrayList<>(); tmp.add(numbers[i]); tmp.add(numbers[left]); tmp.add(numbers[right]); if(list.contains(tmp) == false){ list.add(tmp); } left++; right--; }else if(sum < 0){ left++; }else{ right--; } } } return list; }