Tags: Array
Difficulty:Easy
1. Two Sum:https://leetcode.com/problems/two-sum/
两数和,返回下标数组:(利用HashMap<Key,Value>遍历,其中用到containKey,get(key)--获取value; put<,>;)
<HashMap><Two Pointers>
(1.HashMap,rst; 2.for() / if(containsKey(tar-num[i]))num[1]get/[0]i,return / put(); 3.return)
(有时候题目要求返回数组是基1的,所以是key对于的value都改成i+1了)
1 public class Solution { 2 public int[] twoSum(int[] nums, int target) { 3 HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); 4 int[] rst = new int[2]; 5 for (int i = 0; i < nums.length; i++) { 6 if (map.containsKey(target - nums[i])){ 7 rst[1] = i; 8 rst[0] = map.get(target - nums[i]); 9 return rst; 10 } 11 map.put(nums[i],i); 12 } 13 return rst; 14 } 15 }
26. Remove Duplicates from Sorted Array: https://leetcode.com/problems/remove-duplicates-from-sorted-array/
移除已排序数组的重复元素:<Two Pointers> (指针1遍历,指针2指向'新'数组,如果指针1所指和指针2所指不同则加入,否则跳过。注意:nums[++rst]不能写成nums[rst+1],不然指针没有增长!)
(1.if 2.for()if(rst!i)[++rst],return rst+1;)
1 public class Solution { 2 public int removeDuplicates(int[] nums) { 3 if (nums == null || nums.length == 0 ){ 4 return 0; 5 } 6 int rst = 0; 7 for (Integer num : nums) { 8 if (num != nums[rst]) { 9 nums[++rst] = num; 10 } 11 } 12 return rst + 1; 13 } 14 }
27. Remove Element: https://leetcode.com/problems/remove-element/
移除指定数字:<Two Pointers>
我的解法:(依然是指针1遍历,指针2指向新数组;与指定值不同则加入) 缺点,第一个需要move的元素 后面所有元素都要move;
(1.if 2.for()if(i!val)[rst++],return rst;)
1 public class Solution { 2 public int removeElement(int[] nums, int val) { 3 if (nums == null || nums.length == 0) { 4 return 0; 5 } 6 int rst = 0; 7 for (int i = 0; i < nums.length; i++) { 8 if ( nums[i] != val ) { 9 nums[rst++] = nums[i]; 10 } 11 } 12 return rst; 13 } 14 }
其他解法:(由于题目中说:可以改变元素顺序;考虑移动更少的不数--two pointers从两头往中间走; 为了使i遍历到所有数,while的条件是i<=p,这样最后i=p=last number 如果是val,p--;如果不是val,p;总之rst都是p+1)
(1.i,pointer 2.while(i<=p) if(=)swap,--; else++; return pointer+1)
1 public class Solution { 2 public int removeElement(int[] A, int elem) { 3 int i = 0; 4 int pointer = A.length - 1; 5 while(i <= pointer){ 6 if(A[i] == elem){ 7 A[i] = A[pointer]; 8 pointer--; 9 } else { 10 i++; 11 } 12 } 13 return pointer + 1; 14 } 15 }
↑ 示例:[3,2,3,4,2,5,2]->[3,5,3,4] (过程:先add3,remove2,同时pointer指向的2swap到前面,pointer--;再判断remove2,……)
66. Plus One: https://leetcode.com/problems/plus-one/
数组加一:(常规情况:尾数加1,有9进位;特殊情况,都为9,则数组加一。解法:1.判断末位是否小于9,小于则加1return;2.否则置零判断前一位 循环;3.都为9,则需要添加以为1在首位)
(1.for(n-1,>=0) if(<)++return,[]=0; 2.new int[n+1] [0]=1 return new;)
1 public class Solution { 2 public int[] plusOne(int[] digits) { 3 int n = digits.length; 4 for (int i = n - 1; i >= 0; i--) { 5 if (digits[i] < 9) { 6 digits[i]++; 7 return digits; 8 } 9 digits[i] = 0; 10 } 11 int[] specialCase = new int[n+1]; 12 specialCase[0] = 1; 13 return specialCase; 14 } 15 }
88. Merge Sorted Array: https://leetcode.com/problems/merge-sorted-array/
合并两个有序数组:
解法1:(插入排序思想,需要注意的是指针的变化)
(1.for(j),i,tar; 2.for(i m+j, >tar,--)[i][i-1]; 3.[i]=tar);
1 public class Solution { 2 public void merge(int[] nums1, int m, int[] nums2, int n) { 3 for (int j = 0; j < n; j++) { 4 int i; 5 int tar = nums2[j]; 6 for (i = m + j; i > 0 && nums1[i - 1] > tar; i--) { 7 nums1[i] = nums1[i - 1] ; 8 } 9 nums1[i] = tar; 10 } 11 } 12 }
解法2:(从后向前遍历,大的数插入A数组末尾,3pointers;如果最后nums1已经插完,那么剩下的都是nums2)
(1.i,j,index 2.while(>=0)if(>)([--])else 3.while(j>=0))
1 public class Solution { 2 public void merge(int[] nums1, int m, int[] nums2, int n) { 3 int i = m - 1; 4 int j = n - 1; 5 int index = m + n - 1; 6 while (i >= 0 && j >= 0) { 7 if (nums1[i] > nums2[j]) { 8 nums1[index--] = nums1[i--]; 9 } else { 10 nums1[index--] = nums2[j--]; 11 } 12 } 13 while (j >= 0) { 14 nums1[index--] = nums2[j--]; 15 } 16 } 17 }
118. Pascal's Triangle: https://leetcode.com/problems/pascals-triangle/
帕斯卡三角:
解法1:(在上一行添加一位1;在计算set(j,[j][j+1]))
1 public class Solution { 2 public List<List<Integer>> generate(int numRows) 3 { 4 List<List<Integer>> allrows = new ArrayList<List<Integer>>(); 5 ArrayList<Integer> row = new ArrayList<Integer>(); 6 for(int i=0;i<numRows;i++) 7 { 8 row.add(0, 1); 9 for(int j=1;j<row.size()-1;j++) 10 row.set(j, row.get(j)+row.get(j+1)); 11 allrows.add(new ArrayList<Integer>(row)); 12 } 13 return allrows; 14 15 }
解法2:(直接添加每行的数字)
1 public class Solution { 2 public List<List<Integer>> generate(int numRows) { 3 List<List<Integer>> rst = new ArrayList<List<Integer>>(); 4 for (int i = 0; i < numRows; i++) { 5 List<Integer> row = new ArrayList<Integer>(); 6 for (int j = 0; j < i + 1; j++) { 7 if (j == 0 || j == i) { 8 row.add(1); 9 } else { 10 row.add(rst.get(i - 1).get(j - 1) + rst.get(i - 1).get(j)); 11 } 12 } 13 rst.add(row); 14 } 15 return rst; 16 } 17 }
119. Pascal's Triangle II: https://leetcode.com/problems/pascals-triangle-ii/
求第K行帕斯卡三角:要求O(k)space;
我的解法:递归
1 public class Solution { 2 public List<Integer> getRow(int rowIndex) { 3 List<Integer> rst = new ArrayList<Integer>(); 4 if (rowIndex == 0) { 5 rst.add(1); 6 return rst; 7 } 8 rst = getRow(rowIndex - 1); 9 rst.add(0,1); 10 for (int i = 1; i < rowIndex; i++) { 11 rst.set(i,rst.get(i) + rst.get(i + 1)); 12 } 13 return rst; 14 } 15 }
其他解法:(for循环遍历)
1 public List<Integer> getRow(int rowIndex) { 2 List<Integer> list = new ArrayList<Integer>(); 3 if (rowIndex < 0) 4 return list; 5 6 for (int i = 0; i < rowIndex + 1; i++) { 7 list.add(0, 1); 8 for (int j = 1; j < list.size() - 1; j++) { 9 list.set(j, list.get(j) + list.get(j + 1)); 10 } 11 } 12 return list; 13 }
121. Best Time to Buy and Sell Stock: https://leetcode.com/problems/best-time-to-buy-and-sell-stock/
买卖股票:
我的解法:(Time Limit Exceeded;两个for循环,外循环遍历,内循环求i-n的max, 判断maxPro;嵌套思想:max=Math.max(max,[j]) maxPro=Math.max(maxPro,max-[i]); LeetCode最后一组大数据超时不通过,LintCode可以通过……)
1 public class Solution { 2 public int maxProfit(int[] prices) { 3 int maxPro = 0; 4 for (int i = 0; i < prices.length - 1; i++) { 5 int j; 6 int max = 0; 7 for (j = i + 1; j <prices.length; j++) { 8 max = Math.max(max,prices[j]); 9 } 10 if (max > prices[i]) { 11 maxPro = Math.max(maxPro,max - prices[i]); 12 } 13 } 14 return maxPro; 15 } 16 }
解法:(一次遍历,min记录至今的最小值, maxPro记录至今的最大profit;比较min和price,小于min,那么min易值;大于min那么比较maxPro和price-min的大小)
(1.min,maxPro; 2.for(int) if(<) else(maxPro=Math.max()); 3.return)
1 public class Solution { 2 public int maxProfit(int[] prices) { 3 int maxPro = 0; 4 int min =Integer.MAX_VALUE; 5 for (int price: prices) { 6 if (price < min) { 7 min = price; 8 } else { 9 maxPro = Math.max(maxPro, price - min); 10 } 11 } 12 return maxPro; 13 } 14 }
169. Majority Element: https://leetcode.com/problems/majority-element/
出现次数超过n/2的数:
我的解法:(HashMap<num[i],cnt>;cnt>n/2时return;contains那么cnt++,否则初始化put(,1); 涉及方法:containsKey(), get()--get value, put(Key,value)--可以覆盖)
1 public class Solution { 2 public int majorityElement(int[] nums) { 3 HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); 4 int majorityElement = 0; 5 for (int i = 0; i < nums.length; i++) { 6 if (map.containsKey(nums[i])) { 7 int tmp = map.get(nums[i]); 8 map.put(nums[i],++tmp); 9 } else { 10 map.put(nums[i],1); 11 } 12 if (map.get(nums[i]) > nums.length/2){ 13 majorityElement = nums[i]; 14 return majorityElement; 15 } 16 } 17 return majorityElement; 18 } 19 }
另一个人的HashMap,参考下:
1 public class Solution { 2 public int majorityElement(int[] nums) { 3 int L = nums.length; 4 HashMap<Integer, Integer> map = new HashMap<>(); 5 for(int i=0; i<L; i++) { 6 if(map.containsKey(nums[i])) { 7 if(map.get(nums[i]) >= L/2) 8 return nums[i]; 9 map.replace(nums[i], map.get(nums[i])+1); 10 } 11 else 12 map.put(nums[i], 1); 13 } 14 return nums[L-1]; 15 } 16 }
解法2:(sort排序m,return[n/2];)
1 public class Solution { 2 public int majorityElement(int[] nums) { 3 Arrays.sort(nums); 4 int len = nums.length; 5 return nums[len/2]; 6 } 7 }
解法3:(O(n)timeO(1)space,指针移动,正负计数;most votes of LeetCode)
1 public class Solution { 2 public int majorityElement(int[] num) { 3 4 int major=num[0], count = 1; 5 for(int i=1; i<num.length;i++){ 6 if(count==0){ 7 count++; 8 major=num[i]; 9 }else if(major==num[i]){ 10 count++; 11 }else count--; 12 13 } 14 return major; 15 } 16 }
189. Rotate Array: https://leetcode.com/problems/rotate-array/
向右旋转字符串:
我的解法:(step=k%n; Copy数组,分为两部分改变字符串,前半部分是[i]=[n-step+i],后半部分是[i]=[i-step])(ps:LeetCode有时提交会TLE,有时不会。数据太多的时候耗时多)
(1.n,tmp[],step; 2.if()return; 3.System.arraycopy(); 4.for(0,step)[][n-ste+i]; 5.for(step,n)[][i-step] ;)
1 public class Solution { 2 public void rotate(int[] nums, int k) { 3 int n = nums.length; 4 int[] tmp = new int[n]; 5 int step = k%n; 6 if (nums.length == 0 || step == 0) { 7 return; 8 } 9 System.arraycopy(nums,0,tmp,0,n); 10 for (int i = 0; i < step; i++) { 11 nums[i] = tmp[n - step + i]; 12 } 13 for (int i = step; i < n; i++) { 14 nums[i] = tmp[i - step]; 15 } 16 } 17 }
相似解法:(tmp[]存储[step]的值 O(n) time cost, O(k % nums.length) space cost)
1 public class Solution { 2 public void rotate(int[] nums, int k) { 3 if(nums.length <= 1){ 4 return; 5 } 6 //step each time to move 7 int step = k % nums.length; 8 int[] tmp = new int[step]; 9 for(int i = 0; i < step; i++){ 10 tmp[i] = nums[nums.length - step + i]; 11 } 12 for(int i = nums.length - step - 1; i >= 0; i--){ 13 nums[i + step] = nums[i]; 14 } 15 for(int i = 0; i < step; i++){ 16 nums[i] = tmp[i]; 17 } 18 } 19 }
原地解法:(定义reverse方法;1.全部反转 2.反转(0,k-1)部分 3.反转(k,n-1))
1 public class Solution { 2 public void rotate(int[] nums, int k) { 3 int n = nums.length; 4 k %= n; 5 reverse(nums, 0, n - 1); 6 reverse(nums, 0, k - 1); 7 reverse(nums, k, n - 1); 8 } 9 public void reverse(int[] nums, int start, int end) { 10 while (start < end) { 11 int tmp = nums[end]; 12 nums[end] = nums[start]; 13 nums[start] = tmp; 14 start++; end--; 15 } 16 } 17 }
217. Contains Duplicate: https://leetcode.com/problems/contains-duplicate/
判断数组是否包含重复元素:<HashMap>
我的解法:<HashMap> (O(n),O(n)其实不用HashMap,HashSet即可。补全知识点!)
(1.map; 2.for() if(containsKey()) return;add 3.return false;)
1 public class Solution { 2 public boolean containsDuplicate(int[] nums) { 3 HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); 4 for (int i = 0; i < nums.length; i++){ 5 if (map.containsKey(nums[i])){ 6 return true; 7 } 8 map.put(nums[i],i); 9 } 10 return false; 11 } 12 }
解法2:(Set,利用Set的不重复性,add--if重复,则return false)(PS:TLE)
1 public class Solution { 2 public boolean containsDuplicate(int[] nums) { 3 Set<Integer> set = new HashSet<Integer>(); 4 for(int i : nums) 5 if(!set.add(i))// if there is same 6 return true; 7 return false; 8 } 9 }
解法3:(先sort, 再判断连续重复问题 O(nlgn),O(1))
1 public class Solution { 2 public boolean containsDuplicate(int[] nums) { 3 4 Arrays.sort(nums); 5 for(int ind = 1; ind < nums.length; ind++) { 6 if(nums[ind] == nums[ind - 1]) { 7 return true; 8 } 9 } 10 return false; 11 } 12 }
解法4:(用HashSet改进了我的解法1) (有时AC有时最后的大数据TLE,搞不懂LeetCode判定方法……)
1 public class Solution { 2 public boolean containsDuplicate(int[] nums) { 3 4 Set<Integer> distinct = new HashSet<Integer>(); 5 for(int num : nums) { 6 if(distinct.contains(num)) { 7 return true; 8 } 9 distinct.add(num); 10 } 11 return false; 12 } 13 }
219. Contains Duplicate II:https://leetcode.com/problems/contains-duplicate-ii/
判断是否有重复数字且间隔不大于指定值:
我的解法:<HashMap>(如果已经包含了,那么判断间隔是否小于等于k;如果不包含,put;如果包含了但间隔大于k,那么put覆盖;两种情况可以统一写在if语句外)
(1.map; 2.for() if(containsKey&&<=)return; 3.put; 4.return) (PS: Bug Free! 一次性Accepted)
1 public class Solution { 2 public boolean containsNearbyDuplicate(int[] nums, int k) { 3 HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); 4 for (int i = 0; i < nums.length; i++) { 5 if (map.containsKey(nums[i]) && (i - map.get(nums[i]) <= k)) { 6 return true; 7 } 8 map.put(nums[i],i); 9 } 10 return false; 11 } 12 }
解法2:<HashSet sliding window>(利用长度为k+1的滑动窗口遍历数组;if(i>k)-当开始遍历到大于k+1长度的数字是,每次要remove掉首位; if(!add))true利用set的不重复性;PS:判断语句if()里的add也能执行……)
(1.set; 2.for(0,n) if(>)remove[i-k-1]; 3.if(!add)true 4.false)
1 public class Solution { 2 public boolean containsNearbyDuplicate(int[] nums, int k) { 3 Set<Integer> set = new HashSet<Integer>(); 4 for (int i = 0; i < nums.length; i++) { 5 if (i > k) set.remove(nums[i - k - 1]); 6 if (!set.add(nums[i])) return true; 7 } 8 return false; 9 } 10 }
283. Move Zeroes: https://leetcode.com/problems/move-zeroes/
将0移到最后:(i移动遍历,j指向第一个零,遍历到不为零的,则与第一个零调换)
(for if(!=)swap,j++)
1 public class Solution { 2 public void moveZeroes(int[] nums) { 3 int j = 0; 4 for(int i = 0; i < nums.length; i++) { 5 if(nums[i] != 0) { 6 int temp = nums[j]; 7 nums[j] = nums[i]; 8 nums[i] = temp; 9 j++; 10 } 11 } 12 } 13 }
414. Third Maximum Number: https://leetcode.com/problems/third-maximum-number/
返回第三大的数,如果不存在,返回max:
我的解法:<HashMap> (先将数组排序,然后利用containsValue(),put(index++,num)将不重复的数字放入map中,index对应num的大小顺序;因为最后涉及取出指,所以index作为key,num作为value;不用HashSet,因为HashSet无序,没法取出第三大的数) (PS:运行时间特别长……题目要求是O(n) 解法不符合要求)
(1.sort; 2.map,index; 3.for() if(!containsV)put(index++) 4.if(<3)get(index-1) get(index-3);)
1 public class Solution { 2 public int thirdMax(int[] nums) { 3 Arrays.sort(nums); 4 HashMap<Integer,Integer> map = new HashMap<Integer,Integer>(); 5 int index = 0; 6 for (int num : nums) { 7 if (!map.containsValue(num)) { 8 map.put(index++,num); 9 } 10 } 11 if (index < 3) { 12 return map.get(index - 1); 13 } 14 return map.get(index - 3); 15 } 16 }
解法2:<TreeSet> (利用TreeSet的从小到大排序和不重复性;遍历 添值; 用大小为3的滑动窗口;大于3则remove第一个数; size>=3则返回first,<3则返回last)(注意:定义set的时候只能是TreeSet开头(原因不知?),不然用不了set.first(); set.first(),set.last()是method, 别漏了()) (PS:要先add再remove,这样可以确保add进去的数已经被排序了,并且一次for循环后的size是3) (TreeSet的操作time是O(logn);遍历O(n);size为3,所以是O(n) (not sure))
(1.TreeSet; 2.for()add if() remove; 3.return(<?:))
1 public class Solution { 2 public int thirdMax(int[] nums) { 3 TreeSet<Integer> set = new TreeSet<Integer>(); 4 for (int num : nums) { 5 set.add(num); 6 if (set.size() > 3) { 7 set.remove(set.first()); 8 } 9 } 10 return (set.size() < 3 ? set.last() : set.first()); 11 } 12 }
解法3: first,second,third 三个指针;
448. Find All Numbers Disappeared in an Array: https://leetcode.com/problems/find-all-numbers-disappeared-in-an-array/
长度为n的数组[1,n]中缺失的数:O(n),O(1)
解法:(正负标记法;第一趟,将每个nums[i]所对应的位置(nums[nums[i]-1])的数取负数,如果有重复则跳过; 第二趟, 遍历,正数的位置即为缺失的数.用到方法Math.abs()--取绝对值)
1 public class Solution { 2 public List<Integer> findDisappearedNumbers(int[] nums) { 3 List<Integer> rst = new ArrayList<Integer>(); 4 for (int i = 0; i < nums.length; i++) { 5 int index = Math.abs(nums[i]) - 1; 6 if (nums[index] > 0) { 7 nums[index] = - nums[index]; 8 } 9 } 10 for (int i = 0; i < nums.length; i++) { 11 if (nums[i] > 0) { 12 rst.add(i + 1); 13 } 14 } 15 return rst; 16 } 17 }