LeetCode1-4

LeetCode1-4

两数之和

描述:

给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。

你可以假设每种输入只会对应一个答案。但是,数组中同一个元素不能使用两遍。

示例:

给定 nums = [2, 7, 11, 15], target = 9

因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

思路:

  • 暴力枚举
  • 暴力法很简单,遍历查找每个元素 的值,判断是否存在两个数的和为target。
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[i] + nums[j] == target) {
					return new int[] { i, j };
				}
			}
		}
		throw new IllegalArgumentException("没有找到");
    }
}

缺点就是时间复杂度为O(n^2)

在这里插入图片描述

  • 使用hashmap

因为最近有复习到java中的集合,了解到hashmap的特点,可以有效找到元素与索引的关系,可以使时间复杂度降至O(1)

class Solution {
    public int[] twoSum(int[] nums, int target) {
        Map<Integer, Integer> map = new HashMap<>();
		for(int i = 0; i<nums.length;i++) {
			map.put(nums[i], i);
		}
		
		for(int i = 0;i<nums.length;i++) {
			int c = target - nums[i];
			if(map.containsKey(c) && map.get(c) != i) {
				return new int[] {i,map.get(c)};
			}
		}		
		throw new IllegalArgumentException("没有找到");
    }
}

在这里插入图片描述

两数相加

描述:

给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。

如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。

您可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例:

输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

思路:

按照我们小学学习的两个多位数的相加,从各位开始,各位与各位相加,如果大于10则进位,保留其与10的余数。接下来十位,百位,亦是如此。直到有一个数的没有更高位,则把另一个数的剩余高位补到结果的高位,此时需要判断,是否有进位,如有进位,还需把进位也加之到结果上。

扫描二维码关注公众号,回复: 11406157 查看本文章

这道题主要是对链表的一些操作。

具体步骤:

(1)判断两个链表的所取结点至少有一个不为null(表示相加还未结束)

(2)如果有一个链表索取结点已经为null了,则让其所取数为0,便于另一个数相加。

(3)相加两个所取的数字之和sum

(4)计算sum对10的商值,即目前的进位。

(5)在结果链表上保存当前sum对10的余数,即结果数字的当前位。

(6)将两个链表的指针都指向下一个结点。继续从第(1)步循环进行,直到不满足(1)的条件。

(7)判断是否两数相加结束后仍存在进位,如果有,则在结果链表上创建一个新的结点,用来保存最后一次的进位(结果边界判断)。

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
		ListNode t = new ListNode(0);
		ListNode s = t;
		int c = 0;
		while (l1 != null || l2 != null) {
			int x = l1 == null ? 0 : l1.val;
			int y = l2 == null ? 0 : l2.val;

			int sum = x + y + c;
			c = sum /10;
			sum = sum %10;
			s.next = new ListNode(sum);
			s = s.next;
			if(l1 != null) {
				l1 = l1.next;
			}
			if(l2 != null) {
				l2 = l2.next;
			}
		}
		if(c != 0) {
			s.next = new ListNode(c);
		}

		return t.next;
    }
}

在这里插入图片描述

无重复字符的最长子串

描述:

给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。

示例1:

输入: "abcabcbb"
输出: 3 
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。

示例2:

输入: "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。

示例3:

输入: "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
     请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。

思路: 逐步检查所有的子字符串,找到最大不重复子字符串 ,暴力循环

class Solution {
    public int lengthOfLongestSubstring(String s) {
        //两次循环应该可以搞定
        //1.为空直接退出
        if (s == null) {
            return 0;
        }
        //2.不为空时
        int len = s.length();
        List<Character> list = new ArrayList<>();
        int count = 0;
        for (int i = 0; i < len; i++) {
            for (int j = i; j < len; j++) {
                if (list.contains(s.charAt(j))) {
                    break;
                } else {
                    list.add(s.charAt(j));
                }
            }
            count = Math.max(count, list.size());
            //当count大于等于剩下字符串的长度时,不再遍历
            if (count >= len - 1 - i) {
                break;
            }
            list.clear();
        }
        return count;
    }
}

在这里插入图片描述

寻找两个有序数组的中位数

描述:

给定两个大小为 m 和 n 的有序数组 `nums1` 和 `nums2`。

请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n))。

你可以假设 `nums1` 和 `nums2` 不会同时为空。

示例 1:

nums1 = [1, 3]
nums2 = [2]

则中位数是 2.0

示例 2:

nums1 = [1, 2]
nums2 = [3, 4]

则中位数是 (2 + 3)/2 = 2.5

思路:

把长度为m和长度为n的两个数组的数据放在一个新的数组中,然后对数组进行排序,找到中位数。

找中位数的时候,因为组合后的数组元素个数(m + n)的奇偶性不确定,如果是奇数的话,那么中位数就是第(m+n)/ 2 个元素,如果是偶数的话,那么中位数就是第(m + n )/ 2 个元素和第(m + n)/ 2 + 1个。

我们可以利用int整型向下取整的特点,把上面两种情况归结为一种通用的解法,我们可以找到下标(m + n - 1)/ 2和下标(m + n )/ 2元素,然后求两数的平均值。
class Solution {
    public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int [] result = Arrays.copyOf(nums1, nums1.length + nums2.length);

        /**将一个数组片段复制到另一个数组的指定位置
         * System.arraycopy(src, srcPos, dest, destPos, length)
         * src: 源数组
         * srcPos: 从源数组复制数据的起始位置
         * dest: 目标数组
         * destPos: 复制到目标数组的起始位置
         * length: 复制的长度
         */
        System.arraycopy(nums2, 0, result, nums1.length, nums2.length);     
        Arrays.sort(result);
        double d = (double)(result[(nums1.length +
                                    nums2.length -1)/2] + 
        result[(nums1.length + nums2.length )/2])/2;

        return d;
    }
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/storm_55/article/details/107469256
今日推荐