LeetCode热题100道-Day01

431 阅读2分钟

LeetCode热题100道-Day01

1. 两数之和

  • 可以通过将target - nums[i]的值作为key放入map中,value存具体下标,遍历数组如果能找到这个key存在就代表两数的下标就找到了
class Solution {
    public int[] twoSum(int[] nums, int target) {
        
        if(nums == null || nums.length == 0){
            return new int[]{};
        }
​
        Map<Integer,Integer> map = new HashMap<>();
​
        for(int i = 0;i < nums.length; i++){
            if(map.containsKey(target - nums[i])){
                return new int[]{i,map.get(target-nums[i])};
            }
            map.put(nums[i],i);
        }
​
        return new int[]{};
      
    }
}
func twoSum(nums []int, target int) []int {
​
    if len(nums) == 0{
        return []int{}
    }
​
    hashMap := make(map[int]int)
​
    for i,num := range nums{
​
        if j,ok := hashMap[target-num];ok{
            return []int{i,j}    
        }    
​
        hashMap[num] = i
​
    }
​
    return []int{}
​
}

2. 两数相加

  • 定义一个首尾指针,尾指针指向首,再定义一个进位标记量carry,当l1与l2不为null的情况下,将对应节点的值进行相加并且加上进位标记量carry,尾节点的下一个节点的值为sum= (l1.val + l2.val + carry)%10,那么下一次的carry = sum / 10,然后进行下一次的计算,最后,如果carry大于0,最后一个节点就是carry
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode() {}
 *     ListNode(int val) { this.val = val; }
 *     ListNode(int val, ListNode next) { this.val = val; this.next = next; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
​
        ListNode rh = new ListNode(-1);
        ListNode rt = rh;
        int carry = 0;
​
        while(l1 != null || l2 != null){
​
            int n1 = l1 != null ? l1.val : 0;
            int n2 = l2 != null ? l2.val : 0;
            int sum = n1 + n2 + carry;
            
            rt.next = new ListNode(sum % 10);
            carry = sum/10;
            rt = rt.next;
            
            if(l1 != null){
                l1 = l1.next;
            }
​
            if(l2 != null){
                l2 = l2.next;
            }
​
        }
​
        if(carry > 0){
            rt.next = new ListNode(carry);
        }
​
        return rh.next;
​
    }
}
/**
 * Definition for singly-linked list.
 * type ListNode struct {
 *     Val int
 *     Next *ListNode
 * }
 */
func addTwoNumbers(l1 *ListNode, l2 *ListNode) *ListNode {
    
        rh := new(ListNode)
        rt := rh
        carry := 0
​
        for l1 != nil || l2 != nil {
            
            n1 := 0
            n2 := 0
​
            if l1 != nil{
                n1 = l1.Val
            }
​
            if l2 != nil{
                n2 = l2.Val
            }
​
            sum := n1 + n2 + carry
​
             rt.Next = &ListNode{Val: sum % 10}
            
            carry = sum / 10
​
            rt = rt.Next
​
            if l1 != nil{
                l1 = l1.Next
            }
         
            if l2 != nil{
                l2 = l2.Next
            }
        }
​
        if carry > 0{
            rt.Next = &ListNode{Val: carry}
        }
​
        return rh.Next
       
}

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

  • 使用滑动窗口的方式进行处理,定义一个左右窗口边界l、r,每次循环窗口里面的内容有没有重复来进行左边界和右边界来移动,将每次处理过的边界字符放到一个集合set里,判断下一个字符已经出现过了,就将前一个字符移除掉,然后l++,如果没有出现过就加入集合set里,r++,就能知道每次经历过的窗口长度,也就是说我们只要比较每一次窗口的长度就能知道最大长度是多少
class Solution {
    public int lengthOfLongestSubstring(String s) {
        // 定义窗口的左边界和有边界
        int l = 0,r = 0;
        // 保存最大窗口的长度
        int maxWin = 0;
        // 每次循环窗口里面的内容有没有重复来进行左边界和右边界来移动
        Set<Character> set = new HashSet<>();
        // 不超过字符串长度
        while(l < s.length() && r < s.length()){
          // 判断下一个字符已经出现过了,就将前一个字符移除掉
          if(set.contains(s.charAt(r))){
              set.remove(s.charAt(l));
              // 左边界往右移动
              l++;
          }else{
              set.add(s.charAt(r));
              // 如果不存在就右边界往右移动
              r++;
              maxWin = Math.max(r - l,maxWin);
          }
        }
        return maxWin;
    }
}
func lengthOfLongestSubstring(s string) int {
	// 定义窗口的左边界和右边界
	l := 0
	r := 0
	// 最大窗口的长度
	var maxWin float64
	m := make(map[string]interface{})
	// 每次循环窗口里面的内容有没有重复来进行左边界和右边界来移动
	for l < len(s) && r < len(s) {
		// 如果下一个元素在m存在
		_, ok := m[string(s[r])]
		if ok {
			// 从m中移除前一个元素
			delete(m, string(s[l]))
			// 左边界右移
			l++
		} else {
			m[string(s[r])] = 1
			r++
			maxWin = math.Max(maxWin, float64(r-l))
		}
	}

	return int(maxWin)

}