哈希 (以空间换时间)
1 两数之和
原始的暴力破解的方法:
class Solution {
public int[] twoSum(int[] nums, int target) {
/** 暴力破解的方法 */
int[] result = new int[2];
int length = nums.length;
for(int i = 0;i<length;i++){
for(int j = i+1;j<length;j++){
if(nums[i]+nums[j]==target){
return new int[]{i,j};
}
}
}
return result;
}
}
以空间换时间的写法
class Solution {
public int[] twoSum(int[] nums, int target) {
/** hash时间换空间 */
int[] result = new int[2];
int length = nums.length;
HashMap<Integer,Integer> map = new HashMap<>();
for(int i=0;i<length;i++){
map.put(nums[i],i);
}
for(int i = 0;i<length;i++){
int partA = nums[i];
int partB = target - nums[i];
if(map.get(partB)!=null && map.get(partB)!=i){
result[0] = i;
result[1] = map.get(partB);
}
}
return result;
}
}
2 字母异位词分组
/* 分为两个步骤,一是字符串排序,放到Map中*/
class Solution {
public List<List<String>> groupAnagrams(String[] strs) {
Map<String,List<String>> map = new HashMap<>();
for(String str:strs){
char[] chars = str.toCharArray();
Arrays.sort(chars);
String key = new String(chars);
List<String> list = map.getOrDefault(key,new ArrayList<String>());
list.add(str);
map.put(key,list);
}
return new ArrayList<List<String>>(map.values());
}
}
3 最长连续序列(也可用动态规划)
class Solution {
public int longestConsecutive(int[] nums) {
int length = nums.length;
HashSet<Integer> set = new HashSet<>();
for(int i=0;i<length;i++){
set.add(nums[i]);
}
int max= 0;
for(int j =0;j<length;j++){
if(!set.contains(nums[j]+1)){
int temp = 0;
while(set.contains(nums[j]--)){
temp++;
}
max = Math.max(max,temp);
}
}
return max;
}
}
双指针
移动零
class Solution {
public void moveZeroes(int[] nums) {
int length = nums.length;
int j = 0;
for(int i = 0;i<length;i++ ){
if(nums[i]!=0){
nums[j++] = nums[i];
}
}
for(int k=j;k<length;k++){
nums[k] = 0;
}
return;
}
}
一共两个指针
左指针左边都是非零的数值
使用双指针,左指针指向当前已经处理好的序列的尾部,右指针指向待处理序列的头部。
右指针不断向右移动,每次右指针指向非零数,则将左右指针对应的数交换,同时左指针右移。
注意到以下性质:
1.左指针左边均为非零数;
2.右指针左边直到左指针处均为零。
因此每次交换,都是将左指针的零与右指针的非零数交换,且非零数的相对顺序并未改变。
/* 双指针记方式*/
class Solution {
public void moveZeroes(int[] nums) {
int length = nums.length;
int left = 0;
int right = 0;
for(int i = 0;i<length;i++ ){
if(nums[right]!=0){
// 交换左右的位置
int temp = nums[right];
nums[right] = nums[left];
nums[left] = temp;
left++;
}
right++;
}
return;
}
}