leecode刷题——数组篇
1.两数之和
问题:给定一个整数数组 nums
和一个目标值 target
,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
1)嵌套for循环,使用双指针
for(int i = 0;i<nums.length;i++){ for (int j = nums.length-1;j>i;j--){ if (nums[i]+nums[j]==target){ indexs[0]=i; indexs[1]=j; return indexs; } } }
2)使用hash表进行存储
public int[] twoSum(int[] nums, int target){ int[] indexs = new int[2]; // 建立k-v ,一一对应的哈希表 HashMap<Integer,Integer> hash = new HashMap<Integer,Integer>(); for(int i = 0; i < nums.length; i++){ if(hash.containsKey(nums[i])){ indexs[0] = i; indexs[1] = hash.get(nums[i]); return indexs; } // 将数据存入 key为补数 ,value为下标 hash.put(target-nums[i],i); } return indexs; } }
public int[] twoSum(int[] numbers, int target) { if (numbers == null) return null; int i = 0, j = numbers.length - 1; while (i < j) { int sum = numbers[i] + numbers[j]; if (sum == target) { return new int[]{i + 1, j + 1}; } else if (sum < target) { i++; } else { j--; } } return null; }
2.两数平方和
问题:判断一个非负整数是否为两个整数的平方和。
public boolean judgeSquareSum(int target) { if (target < 0) return false; int i = 0, j = (int) Math.sqrt(target); while (i <= j) { int powSum = i * i + j * j; if (powSum == target) { return true; } else if (powSum > target) { j--; } else { i++; } } return false; }
3.反转字符串中的元音字符
问题:
如:Given s = "leetcode", return "leotcede".
private final static HashSet<Character> vowels = new HashSet<>( Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U')); public String reverseVowels(String s) { if (s==null) return null; int i = 0; int j=s.length()-1; char[] result = new char[s.length()]; while (i<j){ char ci = s.charAt(i); char cj = s.charAt(j); if (!vowels.contains(i)){ result[i++]=ci; }else if (!vowels.contains(j)){ result[j--]=cj; }else{ result[i++]=cj; result[j--]=ci; } } return new String(result); }
4.回文字符串
问题:可以删除一个字符,判断是否能构成回文字符串。
所谓的回文字符串,是指具有左右对称特点的字符串,例如 "abcba" 就是一个回文字符串。
思路:首先使用双指针进行遍历,判断是否相等,不相等删除左边或者右边,在进行判断。
public class Demo04 { public boolean validPalindrome(String s){ for (int i=0,j=s.length()-1;i<j;i++,j--){ if (s.charAt(i)!=s.charAt(j)){ return isPalindrome(s,i+1,j) || isPalindrome(s,i,j-1); } } return true; } private boolean isPalindrome(String s, int i, int j){ while (i<j){ if (s.charAt(i)!=s.charAt(j)){ return false; } } return true; } }
5.归并两个有序数组
如:
Input: nums1 = [1,2,3,0,0,0], m = 3 nums2 = [2,5,6], n = 3 Output: [1,2,2,3,5,6]
public void merge(int[] nums1, int m, int[] nums2, int n) { int index1 = m-1,index2 = n-1; int indexMerge = m + n -1; while (index1>=0||index2>=0){ if (index1<0){ nums1[indexMerge--] = nums2[index2--]; }else if (index2<0){ nums1[indexMerge--] = nums1[index1--]; }else if (nums1[index1]>nums2[index2]){ nums1[indexMerge--]=nums1[index1--]; }else{ nums1[indexMerge--] = nums2[index2--]; } } }
6.判断链表是否存在环
使用双指针,一个指针每次移动一个节点,一个指针每次移动两个节点,如果存在环,那么这两个指针一定会相遇。
public boolean hasCycle(ListNode head){ if (head == null){ return false; } ListNode l1 = head,l2 = head.next(); while (l1 != null && l2 != null && l2.next!= null){ if (l1==l2){ return true; } l1 = l1.next; l2 = l2.next.next; } return false; }
7.最长子序列
题目描述:删除 s 中的一些字符,使得它构成字符串列表 d 中的一个字符串,找出能构成的最长字符串。
如果有多个相同长度的结果,返回字典序的最小字符串。
Input:s = "abpcplea", d = ["ale","apple","monkey","plea"]
Output:"apple"
public String findLongestWord(String s, List<String> d) { String longestWord = ""; for (String target :d) { int l1 = longestWord.length(), l2 = target.length(); if (l1 > l2 || (l1 == l2 && longestWord.compareTo(target) < 0)) { continue; } if (isSubstr(s, target)) { longestWord = target; } } return longestWord; } private boolean isSubstr(String s, String target) { int i = 0, j = 0; while (i < s.length() && j < target.length()) { if (s.charAt(i) == target.charAt(j)) { j++; } i++; } return j == target.length(); }