leetcode 1~3

22.2.25刷

顺便记录一些API

1. Two Sum

Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.You may assume that each input would have exactly one solution, and you may not use the same element twice.You can return the answer in any order.

思路

用一个哈希表放前面遍历过的,key----nums[i],value----i,这是因为可以利用其方法containsKey来查询前面是否出现了target-nums[i],get方法可以获得对应的value
c++: find查 , find() 返回的指针->second 找到 value
//java
class Solution {
    public int[] twoSum(int[] nums, int target) {
        int len = nums.length;
        int[] ans = new int[2];
        HashMap<Integer, Integer> map = new HashMap<>();
        for(int i = 0; i < len; i++){
            if(map.containsKey(target - nums[i])){
                ans[0] = map.get(target - nums[i]);
                ans[1] = i;
                return ans;
            }
            map.put(nums[i], i);
        }
        return new int[0];
    }
}
//c++
class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        int len = nums.size();
        unordered_map<int, int> map;
        for(int i = 0; i < len; i++){
            auto it = map.find(target - nums[i]);
            if(it != map.end()){
                return {it -> second, i};
            }
            map[nums[i]] = i;
        }
        return {};
    }
};

收获(java)

在这里插入图片描述
好文链接!!

HashTable vs HashMap : 前者线程安全,后者不安全,但效率高
常用的方法
put(key,value)
查询是否包含某键containsKey()
得到键对应的值get(key)
空否isEmpty()

收获(c++)

unordered_map<int, int> map;//创建哈系表
auto it = map.find(key);//找,如果查到了返回value的指针,,否则,返回map.end()指针
it -> second   // 对应的value

//vector.size(); .push_back();

2. Add Two Numbers

You are given two non-empty linked lists representing two non-negative integers. The digits are stored in reverse order, and each of their nodes contains a single digit. Add the two numbers and return the sum as a linked list.
You may assume the two numbers do not contain any leading zero, except the number 0 itself.

此题的关键点在于最后遍历完了,如果还有进位。

因为比较菜,刚开始做的时候出了挺多问题的,日后可以再回顾这个题。

//java
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode ans = new ListNode(0);
        ListNode dummy = ans;//虚拟头节点
        int sum = 0;
        int carry = 0;
        while(l1 != null || l2 != null){
            int x1 = l1 != null ? l1.val : 0;
            int x2 = l2 != null ? l2.val : 0;
            sum = x1 + x2 + carry;
            carry = sum / 10;
            if(l1 != null) l1 = l1.next;
            if(l2 != null) l2 = l2.next;
            ans.next = new ListNode(sum % 10);
            ans = ans.next;
        }
        if(carry > 0)
            ans.next = new ListNode(1);
        return dummy.next;
    }
}

注意了,上面的虚拟头节点非常重要,这样便可以简化代码。如果不用,代码如下:

class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
        ListNode ans = null;
        ListNode head = null;//别省略,省略后就报错
        int sum = 0;
        int carry = 0;
        while(l1 != null || l2 != null){
            int x1 = l1 != null ? l1.val : 0;
            int x2 = l2 != null ? l2.val : 0;
            sum = x1 + x2 + carry;
            carry = sum / 10;
            if(l1 != null) l1 = l1.next;
            if(l2 != null) l2 = l2.next;
            if(head == null){
                head = ans = new ListNode(sum % 10);
            }
            else{
                ans.next = new ListNode(sum % 10);   
                ans = ans.next;
            }
        }
        if(carry > 0)
            ans.next = new ListNode(1);
        return head;
    }
}

收获满满

关于定义与声明可以看这篇,讲的很好:
好文

可以看到初始化非常重要!!!!!!!!

//c++
class Solution {
public:
    ListNode* addTwoNumbers(ListNode* l1, ListNode* l2) {
        ListNode *head = nullptr, *tail = nullptr; //当然这里也可以像上面一样,用一个虚拟头节点来初始化
        int carry = 0;
        while (l1 || l2) {
            int n1 = l1 ? l1->val: 0;
            int n2 = l2 ? l2->val: 0;
            int sum = n1 + n2 + carry;
            if (!head) {
                head = tail = new ListNode(sum % 10);
            } else {
                tail->next = new ListNode(sum % 10);
                tail = tail->next;
            }
            carry = sum / 10;
            if (l1) {
                l1 = l1->next;
            }
            if (l2) {
                l2 = l2->next;
            }
        }
        if (carry > 0) {
            tail->next = new ListNode(carry);
        }
        return head;
    }
};

c++ 的null要写为nullptr

这道题让我真正体会到了,总是只看代码,写的少是绝对不行的,虽然思路非常简单,但是由于我的代码写的少,直接寄。


3. Longest Substring Without Repeating Characters

思路容易想,但是实现没漏洞还是改了好久,值得以后再刷

//哈希表+滑动窗口 beat 56%
class Solution {
    public int lengthOfLongestSubstring(String s) {
        HashMap<Character, Integer> map = new HashMap<>();
        int len = s.length();
        int left = 0, ans = 0;
        for(int i = 0; i < len && left < len - ans; i++){	//剪枝
            char ch = s.charAt(i);
            if(map.containsKey(ch)){
                left = Math.max(left, map.get(ch) + 1); //关键,查到的重复字符,可能是在左指针的左边
            }
            ans = Math.max(ans, i - left + 1);
            map.put(ch, i);
        }
        return ans;
    }
}

//优化 : 用数组模拟哈系表 beat 100%
class Solution {
    public int lengthOfLongestSubstring(String s) {

        int max = 0;
        int len = s.length();
        int i = 0;
        // HashMap<Character, Integer> map = new HashMap<>();
        int[]  map = new int[210];
        for(int k = 0; k < 210; k++) map[k] = -1; //也可以 Arrays.fill(map, -1);
        for(int j = 0; j < len && i < len - max; j++){
            char c = s.charAt(j);
            if((map[c] != -1)){
                i = Math.max(map[c] + 1, i);
            }
            max = Math.max(max, j - i +1);
            map[c] = j;
        }
        return max;
    }
}
//c++
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        int max = 0;
        int len = s.length();
        int i = 0;
        int map[210];
        for(int k = 0; k < 210; k++) map[k] = -1;
        for(int j = 0; j < len && i < len - max; j++){
            char c = s[j];
            if((map[c] != -1)){
                i = map[c] + 1 > i ? map[c] + 1 : i;
            }
            max = max > j - i + 1 ? max : j - i + 1;
            map[c] = j;
        }
        return max;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值