leetCode Part 1

1. 两数之和

1. 题目

1. 两数之和
给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标。
你可以假设每种输入只会对应一个答案。但是,你不能重复利用这个数组中同样的元素。
示例:
给定 nums = [2, 7, 11, 15], target = 9
因为 nums[0] + nums[1] = 2 + 7 = 9
所以返回 [0, 1]

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/two-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2.代码

2.1 暴力法
2.2 (优解)利用map做哈希表
import java.util.HashMap;
import java.util.Map;

class Solution1 {
  public static void main(String[] args) {
    Solution1 solution = new Solution1();
    int[] result = solution.twoSum(new int[] {3, 2, 4}, 6);
    for (int i = 0; i < result.length; i++) {
      System.out.println(result[i]);
    }
  }

  /**
   * 暴力法
   * @param nums
   * @param target
   * @return
   */
  public int[] twoSum1(int[] nums, int target) {
    for (int i = 0; i < nums.length - 1; i++) {
      for (int j = i + 1; j < nums.length; j++) {
        if (nums[i] + nums[j] == target) {
          return new int[]{i, j};
        }
      }
    }
    throw new IllegalArgumentException("No two sum solution");
  }

  /**
   * (优解)利用map做哈希表
   * @param nums
   * @param target
   * @return
   */
  public int[] twoSum(int[] nums, int target) {
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    for (int i = 0; i < nums.length; i++) {
      int needNumber = target - nums[i];
      if (map.containsKey(needNumber)) {
        return new int[]{map.get(needNumber), i};
      } else {
        map.put(nums[i], i);
      }

    }
    throw new IllegalArgumentException("No two sum solution");
  }
}

4. 算法用时

语言 方法 执行用时 内存消耗
Java 暴力法 5 ms 36.8 MB
Java 利用map做哈希表 23 ms 37.9 MB

5. 感想

两种方法在性能方面差很多,所以解题时多用数据结构有利于提升性能。

2. 两数相加

1. 题目

2. 两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2.代码

2.1 处理各种情景 将结果集放入l1中
2.2 (优解)官方解答(有修改)
import leet.code.entity.ListNode;

/*
2. 两数相加
给出两个 非空 的链表用来表示两个非负的整数。其中,它们各自的位数是按照 逆序 的方式存储的,并且它们的每个节点只能存储 一位 数字。
如果,我们将这两个数相加起来,则会返回一个新的链表来表示它们的和。
您可以假设除了数字 0 之外,这两个数都不会以 0 开头。
示例:
输入:(2 -> 4 -> 3) + (5 -> 6 -> 4)
输出:7 -> 0 -> 8
原因:342 + 465 = 807

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/add-two-numbers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
 */
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution2 {
  public static void main(String[] args) {
    Solution2 solution = new Solution2();
    int[] l1Arr = new int[] {2, 4, 3};
    int[] l2Arr = new int[] {5, 6, 4};

    ListNode l1 = solution.creatLink(l1Arr);
    ListNode l2 = solution.creatLink(l2Arr);

    solution.addTwoNumbers(l1, l2);
  }

  private ListNode creatLink(int[] l1Arr) {
    if (l1Arr == null || l1Arr.length == 0) {
      return null;
    }

    ListNode head = null;
    ListNode pre = null;
    for (int i = 0; i < l1Arr.length; i++) {
      ListNode tem = new ListNode(l1Arr[i]);
      if (i == 0) {
        head = tem;
      } else {
        pre.next = tem;
      }
      pre = tem;
    }
    return head;
  }

  /**
   * 处理各种情景 将结果集放入l1中
   * @param l1
   * @param l2
   * @return
   */
  public ListNode addTwoNumbers1(ListNode l1, ListNode l2) {
    boolean carry = false;
    ListNode l1pre = null;
    ListNode result = l1;
    while (l1 != null || l2 != null || carry) {
      // l1 + l2
      int sum;
      if (l1 != null && l2 != null) {
        sum = l1.val + l2.val;
      } else if (l1 == null) {
        l1 = new ListNode(0);
        if (l1pre != null) {
          l1pre.next = l1;
        }
        if (l2 != null) {
          sum = l1.val + l2.val;
        } else {
          sum = 0;
        }
      } else {
        //l1 != null && l2 == null
        sum = l1.val;
      }
      // 处理上一次进位
      if (carry) {
        sum++;
        carry = false;
      }
      // 处理当前进位
      if (sum > 9) {
        sum -= 10;
        carry = true;
      }
      //赋值
      l1.val = sum;
      l1pre = l1;
      if (l1 != null) l1 = l1.next;
      if (l2 != null) l2 = l2.next;
    }

    return result;
  }


  /**
   * 官方解答(有修改) 优解
   * @param l1
   * @param l2
   * @return
   */
  public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
    ListNode dummyHead = new ListNode(0);
    ListNode curr = dummyHead;
    int carry = 0;
    while (l1 != null || l2 != null) {
      int x = (l1 != null) ? l1.val : 0;
      int y = (l2 != null) ? l2.val : 0;
      int sum = carry + x + y;
      carry = sum / 10;
      curr.next = new ListNode(sum % 10);
      curr = curr.next;
      if (l1 != null) l1 = l1.next;
      if (l2 != null) l2 = l2.next;
    }
    if (carry > 0) {
      curr.next = new ListNode(carry);
    }
    return dummyHead.next;
  }
}

4. 算法用时

/
| 语言 | 方法 | 执行用时 | 内存消耗 |
| --- | --- | --- | --- |
| Java | 处理各种情景 | 2 ms | 44.2 MB |
| Java | 官方解答 | 2 ms | 44.7 MB |
/

5. 感想

两种算法相差无几,就是思考方式不同,一种是将所有可能都罗列出来,另一种是综合考虑。

猜你喜欢

转载自www.cnblogs.com/demogc/p/12004003.html