【力扣hot100】day1

1、两数之和【易】

1. 两数之和

一:暴力

  • 时间复杂度:O(N^2)
  • 空间复杂度:O(1)
//执行用时: 49 ms
//内存消耗: 38.2 MB
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int [] arr=new int[2];
        for(int i=1;i<nums.length;i++){
            for(int j=0;j<i;j++){
                if(nums[j]+nums[i]==target){
                    arr[0]=j;
                    arr[1]=i;
                }
            }
        }
        return arr;
    }
}

暴力2(时间、空间复杂度同上)

//执行用时: 55 ms
//内存消耗: 41.7 MB
class Solution {
    public int[] twoSum(int[] nums, int target) {
        for(int i=0;i<nums.length;i++){
            for(int j=i+1;j<nums.length;j++){
                if(nums[j]+nums[i]==target){
                    return new int[] {i,j};
                }
            }
        }
        return new int[-1];
    }
}

二:哈希表
哈希表1:

  • 时间复杂度:O(N)
  • 空间复杂度:??
//执行用时: 4 ms
//内存消耗: 42.1 MB
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int[] res = new int[2];
        if(nums == null || nums.length == 0){
            return res;
        }
        HashMap<Integer, Integer> map = new HashMap<>();
        //Map<Integer, Integer> map = new HashMap<>();也行
        for(int i = 0; i < nums.length; i++){
            int temp = target - nums[i];
            if(map.containsKey(temp)){
                res[1] = i;
                res[0] = map.get(temp);
            }
            map.put(nums[i], i);
    }
    return res;
    }
}

哈希表2:
优化:

//执行用时: 1 ms
//内存消耗: 41.3 MB
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        int[] arr = new int[2];
        for(int i = 0; i < nums.length; i++) {
            int tmp = target - nums[i];
            if(map.containsKey(tmp)) {
                arr[0] = map.get(tmp);
                arr[1] = i;
                return arr; //优化主要体现在这一步,如果符合条件,就提前结束循环
            }
            map.put(nums[i], i);
        }
        return nums;
    }
}

哈希表3:

  • 时间复杂度:O(N)
  • 空间复杂度:O(N)
//执行用时: 2 ms
//内存消耗: 41.4 MB
class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++) {
            int tmp = target - nums[i];
            if(map.containsKey(tmp)) {
                int j = map.get(tmp);
                return new int[]{i, j};
            }
            map.put(nums[i], i);
        }
        return new int[]{-1, -1};
    }
}

2、两数相加【中】

2. 两数相加

//执行用时: 1 ms
//内存消耗: 41.6 MB
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode dummy = new ListNode(0);
        ListNode cur = dummy;
        int n = 0;
        while(l1 != null || l2 != null || n != 0) {
            if(l1 != null) {
                n += l1.val;
                l1 = l1.next;
            }
            if(l2 != null) {
                n += l2.val;
                l2 = l2.next;
            }
            cur.next = new ListNode(n % 10);
            cur = cur.next;
            n /= 10;
        }
        return dummy.next;
    }
}

3、无重复字符串的最长子串【中】

3. 无重复字符串的最长子串

一:哈希表、滑动窗口

//执行用时: 4 ms
//内存消耗: 41.7 MB
class Solution {
    public int lengthOfLongestSubstring(String s) {
        Map<Character, Integer> map = new HashMap<>();
        int len = 0;
        for(int left = 0, right = 0; right < s.length(); right++) {
            char c = s.charAt(right);
            if(map.containsKey(c)) {
                left = Math.max(map.get(c), left);//left取最右边的位置
            }
            len = Math.max(len, right - left +1);
            map.put(s.charAt(right), right + 1);
        }
        return len;
    }
}

二:滑动窗口

  • 滑动窗口,保证每个窗口里字母都是唯一的
  • 使用 int[] m来记录一个字母如果后面出现重复时,i 应该调整到的新位置21。 所以每次更新的时候都会保存 j + 1 ,即字母后面的位置
  • j 表示子串的最后一个字母,计算子串长度为 j - i + 1
//执行用时: 1 ms
//内存消耗: 41.4 MB
class Solution {
    public int lengthOfLongestSubstring(String s) {
        int[] m = new int[128];
        int len = 0;
        for(int i = 0, j = 0; j < s.length(); j++){
            i = Math.max(m[s.charAt(j)], i);
            len = Math.max(len, j - i + 1);
            m[s.charAt(j)] = j + 1;
        }
        return len;
    }
}

4、寻找两个正序数组的中位数【难】

4. 寻找两个正序数组的中位数

//执行用时: 3 ms
//内存消耗: 42.5 MB
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int len1 = nums1.length, len2 = nums2.length;
        int len = len1 + len2;
        int[] ans = new int[len];
        for(int i = 0; i < len1; i++) {
            ans[i] = nums1[i];
        } 
        for(int i = len1; i < len; i++) {
            ans[i] = nums2[i - len1];
        }
        Arrays.sort(ans);
        int left = 0, right = len - 1;
/*
        while(left < right) {
            left++;
            right--;
        }
*/
        if(len % 2 != 0) return (1.0 * ans[len / 2]);
        return (1.0 * (ans[len / 2 - 1] + ans[len / 2]) / 2);
    }
}

5、最长回文子串【中】

5. 最长回文子串
方法一:

//执行用时: 104 ms
//内存消耗: 44.9 MB
class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        if(len < 2) return s;
        boolean[][] dp = new boolean[len][len];//dp[i][j]:表示s[i][j]是否是回文串
        int Imax = 1;
        int Imin = 0;
        char[] ss = s.toCharArray();
        for(int i = 0; i < len; i++) {
            dp[i][i] = true;// 初始化:单独一个字符肯定是回文子串
        }
		// 经验:dp区域是正方形的话,通常左下角区域无效不需要再填,因为走过的区域不用再走
        for(int j = 1; j < len; j++) { // 上三角区域,按列从上到下填
            for(int i = 0; i < j; i++) {
                if(ss[i] != ss[j]) { // 首尾不相等时,必不是回文串
                    dp[i][j] = false;
                } else {
                	//首尾相等时,有2种情况
                    // 情况1:s[i...j]长度不超过3,不用检查必为回文串
                    // 情况2:s[i...j]长度大于3,由s[i+1...j-1]来判断
                    dp[i][j] = j - i + 1 <= 3 || dp[i + 1][j - 1];
                }

                if(dp[i][j] && j - i + 1 > Imax) {
                    Imax = j - i + 1;
                    Imin = i;
                }
            }
        }
        return s.substring(Imin, Imin + Imax);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值