0
点赞
收藏
分享

微信扫一扫

阿翰剑指offer专项突破Day02

眼君 2022-01-23 阅读 77

目录

第 2 天 整数 

1 只出现一次的数字 

1. 哈希表

2. 位运算 

3. 有限自动机

2 单词长度的最大乘积

1. 暴力法

2. 哈希表

3. 整数的二进制数位记录出现的字符

3 排序数组中两个数字之和

1. 遍历

2.双指针法


第 2 天 整数 

1 只出现一次的数字 

剑指 Offer II 004. 只出现一次的数字 icon-default.png?t=M0H8https://leetcode-cn.com/problems/WGki4K/

1. 哈希表

class Solution {
    public int singleNumber(int[] nums) {
        Map<Integer, Integer> freq = new HashMap<Integer, Integer>();
        for (int num : nums) {
            freq.put(num, freq.getOrDefault(num, 0) + 1);
        }
        int ans = 0;
        for (Map.Entry<Integer, Integer> entry : freq.entrySet()) {
            int num = entry.getKey(), occ = entry.getValue();
            if (occ == 1) {
                ans = num;
                break;
            }
        }
        return ans;
    }
} 

2. 位运算 

使用位运算将空间复杂度降低到O(1)。一般面试官会加上这个限制!

对于每一位的数字,除了目标数字外,每一个元素都出现 3 次,对应着第 i 个二进制位的 3 个 0 或 3 个 1,无论是哪一种情况,它们的和都是 3 的倍数(即和为 0 或 3)。借此目标数字的第 i 个二进制位就是数组中所有元素的第 i 个二进制位之和除以 3 的余数。

注意:

  1. 位运算 (x >> i) & 1 得到 x 的第 i 个二进制位
    1. 将它们相加再对 3 取余,得到的结果一定为 0 或 1,即为答案的第 i 个二进制位。
  2. 位运算 ans |=(1 << i ) 对结果每一个二进制位进行赋值。
class Solution {
    public int singleNumber(int[] nums) {
        int ans = 0;
        for (int i = 0; i < 32; ++i) {
            int total = 0;
            for (int num: nums) {
                total += ((num >> i) & 1);
            }
            if (total % 3 != 0) {
                ans |= (1 << i);
            }
        }
        return ans;
    }
}

3. 有限自动机

数电思想

2 单词长度的最大乘积

剑指 Offer II 005. 单词长度的最大乘积icon-default.png?t=M0H8https://leetcode-cn.com/problems/aseY1I/

1. 暴力法

O(pq)

2. 哈希表

对每个字符串适用26个英文字母这个长度的哈希表存储出现在其中的字符。

在哈希表中查 O(1)。可以看做在应用哈希表后,判断两个字符串是否包含相同字符的时间复杂度为(1)。

class Solution {
    public int maxProduct(String[] words) {
        boolean[][] flags = new boolean[words.length][26];
        for (int i = 0; i < words.length; i++) {
            for(char c : words[i].toCharArray()){
                flags[i][c-'a'] = true;
            }
        }
        int result = 0;
        for (int i = 0; i < words.length; i++) {
            for (int j = 0; j < words.length; j++) {
                int k = 0;
                for (; k < 26; k++){
                    if(flags[i][k] && flags[j][k])
                        break;
                }
                if(26 == k){
                    int prod = words[i].length() * words[j].length();
                    result = Math.max(result, prod);
                }
            }
        }
        return result;
    }
}

分析代码

共两步,第一步初始化哈希表 O(words的长度n * 平均字符串长度k),第二步 判断每对字符串是否包含相同字符 O(1) * O(n*n),总体上是O(nk+n*n)。

空间复杂度则是n*26 即O(n)

3. 整数的二进制数位记录出现的字符

记录是否出现使用的是布尔型数组,也可以利用二进制!

Java中int型整数二进制有32位,so~

class Solution {
    public int maxProduct(String[] words) {
        int[] flags = new int[words.length];
        for (int i = 0; i < words.length; i++) {
            for (char c : words[i].toCharArray()) {
                flags[i] |= 1 << (c - 'a');
            }
        }
        int result = 0;
        for (int i = 0; i < words.length; i++) {
            for (int j = 0; j < words.length; j++) {
                if ((flags[i] & flags[j]) == 0) {
                    int prod = words[i].length() * words[j].length();
                    result = Math.max(result, prod);
                }
            }
        }
        return result;
    }
}

 

3 排序数组中两个数字之和

剑指 Offer II 006. 排序数组中两个数字之和icon-default.png?t=M0H8https://leetcode-cn.com/problems/kLl5u1/

1. 遍历

2.双指针法

package zxtp.Day01;

import java.util.Arrays;

/**
 * @author ahan
 * @create_time 2022-01-23-6:10 下午
 */
public class _006 {
    public static void main(String[] args) {
        System.out.println(Arrays.toString(new _006().twoSum(new int[]{1,2,4,6,10}, 8)));
    }
    public int[] twoSum(int[] numbers, int target) {
        int[] res = new int[2];
        for (int i = 0, j = numbers.length - 1; i <= j; ) {
            int sum = numbers[i] + numbers[j];
            System.out.println(sum);
            if(sum == target){
                res[0] = i;
                res[1] = j;
                break;
            }

            else if(sum > target)
                j--;
            else
                i++;
        }
        return res;
    }

}

 

举报

相关推荐

0 条评论