Leetcode刷题打卡(三数之和,爬楼梯问题,反转链表,有效的括号)|刷题打卡

280 阅读1分钟

1.三数之和 LeetCode 15题


题解: 1.先对数组排序再循环,因为排序完当循环到nums[i]>0的时候,后面的无须循环因为最左侧是正数,三个正数的和不可能是0,因为三数之和是nums[i]+nums[i+1]+nums[nums.length - 1]即nums[i]大于0 三数之和不可能为0即退出整个循环break 2.循环整个数组,i > 0 && nums[i - 1] == nums[i]是为了判断相同的值,发现当前值和前一个值相等直接continue 3.然后while (left < right)循环就是定义左右两个结点加上自己循环的nums[i],我们定死nums[i]让left=nums[i+1]和right=nums[nums.length - 1]两边往往中间走。 4.大的判断,当三数之和sum==0返回,当三数之和小于0因为是有序的,肯定是左边的不够大需要left++,反之三数之和大于0就是right太大需要right-- 5.再想sum==0的时候因为题意要求不止一组满足sum==0,当sum等于0的时候需要继续往中间走继续找满足的条件,很容易想到直接让left++;和right--再往中间走的时候左右两边遇见重复的直接各自left++和right--

  public List<List<Integer>> threeSum(int[] nums) {
    List<List<Integer>> array = new ArrayList<>();

    if (nums == null || nums.length < 3) {
        return array;
    }
    Arrays.sort(nums);
    for (int i = 0; i < nums.length; i++) {
        if (nums[i] > 0) {
            break;
        }
        if (i > 0 && nums[i - 1] == nums[i]) {
            continue;
        }
        int left = i + 1;
        int right = nums.length - 1;
        while (left < right) {
            int temp = nums[left] + nums[right] + nums[i];
            if (temp == 0) {
                array.add(Arrays.asList(nums[i], nums[left], nums[right]));
                while (left < right && nums[left] == nums[left + 1]) {
                    left++;
                }
                while (left < right && nums[right] == nums[right - 1]) {
                    right--;
                }
                left++;
                right--;
            } else if (temp < 0) {
                left++;
            } else if (temp > 0) {
                right--;

            }
        }
    }
    return array;
}

爬楼梯 LeetCode 70题

题解:从第一层往上人肉想很难想通,如果你倒着想,你在第n阶台阶只能从第n-1阶台阶上来,或者从n-2阶台阶上来,那么有f(n)=f(n-1)+f(n-2)dp方程就是dp[i] = dp[i - 1] + dp[i - 2]。这是自顶向下,如果自底向上就是,除过第1个值和第2个值,每个值都依赖前两个值相加,那么申请三个临时变量,一直往上递推,变三个变量的值,循环完返回最后一个值。

public int climbStairs(int n) {
    //1 返回1
    if (n == 1) {
        return 1;
    }
    //定义第一步
    int first = 1;
    //定义第二部
    int second = 2;
    //三步以上每前一步替换后一步,递推上去,自底向上
    for (int i = 3; i <= n; i++) {
        int third = first + second;
        first = second;
        second = third;

    }
    return second;

}

反转链表 LeetCode 206题

题解:见注释

public ListNode reverseList(ListNode head) {
    //申请 三个变量交换
    ListNode pre=null;
    ListNode cur=head;
    ListNode tem=null;
    //当当前节点不为空时
    while(cur!=null){
        //临时变量是当前节点的下一个
        tem=cur.next;
        //当前节点指回去上一个节点
        cur.next=pre;
        //pre和cur节点都前进一位
        //当前节点变成前一个节点
        pre=cur;
        //临时节点就是当前节点
        cur=tem;
    }
    return pre;
}

有效的括号 LeetCode 20题

题解:我在不知道这种解法之前对这个题无从下抓,当我知道这种解法的时候,只一次我每次都能正确的写出这个题解,很好理解。 1.初始化一个栈,循环整个字符,当发现是 “(” 和 “[” 和 “{” 依次往栈里面对应的另一半也就是“)”和 “]” 和 “}” 除过这三种情况判断栈是否空了,如果是空那么就是我有右括号,你栈里面没有对应的左括号,如果不为空让栈顶元素出栈,和当前元素比较,如果不相等那么就是当前这一对括号不匹配,这两种情况都返回false,反之栈不为空,栈顶元素和当前循环的值相等说明匹配上了,继续用相同的方法匹配下一个值。整个循环完之后如果栈是空的说明正好全部匹配完返回true,如果栈不是空说明有多余的左括号返回false。

public boolean isValid(String s) {
    Stack<Character> stack = new Stack<Character>();
    for (char c : s.toCharArray()) {
        if (c == '(')
            stack.push(')');
        else if (c == '{')
            stack.push('}');
        else if (c == '[')
            stack.push(']');
        else if (stack.isEmpty() || stack.pop() != c)
            return false;
    }
    return stack.isEmpty();
}