算法面试 | 40天刷完LeetCode 精选 TOP 面试题(2/40)

 个人主页:天海奈奈的博客
刷题专栏: 题库 - 力扣 (LeetCode) 全球极客挚爱的技术成长平台面试top
刷题网站:  力扣 让我们一起加油~

目录

 20. 有效的括号

 21. 合并两个有序链表

26. 删除有序数组中的重复项

2. 两数相加


 20. 有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。
左括号必须以正确的顺序闭合。
每个右括号都有一个对应的相同类型的左括号。

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

示例 1:

输入:s = "()"
输出:true
示例 2:

输入:s = "()[]{}"
输出:true
示例 3:

输入:s = "(]"
输出:false

这个题我们需要判断所给的字符串中的前后括号是否能成对存在,也就是一一对应的关系。

既然括号是成对存在并且我们只需要判断对错,根据括号一一对应的性质我们考虑红使用栈的方法来解决,遍历的时候出现左括号我们就将对应的右括号入栈,利用栈的同进同出的性质,当遍历到右括号时如果右括号存在且在栈顶,我们就出栈如果没有或不是同一种类我们就出栈

代码实现

class Solution {
    public boolean isValid(String s) {
     Stack<Character> stack = new Stack<>();
    char[] chars = s.toCharArray();
    //遍历所有的元素
    for (char c : chars) {
        //如果是左括号,就把他们对应的右括号压栈
        if (c == '(') {
            stack.push(')');
        } else if (c == '{') {
            stack.push('}');
        } else if (c == '[') {
            stack.push(']');
        } else if (stack.isEmpty() || stack.pop() != c) {
            //否则就只能是右括号。
            //1,如果栈为空,说明括号无法匹配。
            //2,如果栈不为空,栈顶元素就要出栈,和这个右括号比较。
            //如果栈顶元素不等于这个右括号,说明无法匹配,
            //直接返回false。
            return false;
        }
    }
    //最后如果栈为空,说明完全匹配,是有效的括号。
    //否则不完全匹配,就不是有效的括号
    return stack.isEmpty();


    }
}

 21. 合并两个有序链表

这个题我们要合并两个有序链表,我们新建一个链表,只要有一个链表没完我们就不停,比对两个链表当前节点的大小,将小的接入新建链表,一个链表空了就直接接入未空链表。

 代码实现

/**
 * 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 mergeTwoLists(ListNode list1, ListNode list2) {
        ListNode dummyHead = new ListNode(0);
        ListNode cur = dummyHead;
        while (list1 != null && list2 != null) {
            if (list1.val < list2.val) {
                cur.next = list1;
                cur = cur.next;
                list1 = list1.next;
            } else {
                cur.next = list2;
                cur = cur.next;
                list2 = list2.next;
            }
        }
        // 任一为空,直接连接另一条链表
        if (list1 == null) {
            cur.next = list2;
        } else {
            cur.next = list1;
        }
        return dummyHead.next;
    }
}

26. 删除有序数组中的重复项

给你一个 升序排列 的数组 nums ,请你 原地 删除重复出现的元素,使每个元素 只出现一次 ,返回删除后数组的新长度。元素的 相对顺序 应该保持 一致 。

由于在某些语言中不能改变数组的长度,所以必须将结果放在数组nums的第一部分。更规范地说,如果在删除重复项之后有 k 个元素,那么 nums 的前 k 个元素应该保存最终结果。

将最终结果插入 nums 的前 k 个位置后返回 k 。

不要使用额外的空间,你必须在 原地 修改输入数组 并在使用 O(1) 额外空间的条件下完成。

判题标准:

系统会用下面的代码来测试你的题解:

int[] nums = [...]; // 输入数组
int[] expectedNums = [...]; // 长度正确的期望答案

int k = removeDuplicates(nums); // 调用

assert k == expectedNums.length;
for (int i = 0; i < k; i++) {
    assert nums[i] == expectedNums[i];
}
如果所有断言都通过,那么您的题解将被 通过。

示例 1:

输入:nums = [1,1,2]
输出:2, nums = [1,2,_]
解释:函数应该返回新的长度 2 ,并且原数组 nums 的前两个元素被修改为 1, 2 。不需要考虑数组中超出新长度后面的元素。
示例 2:

输入:nums = [0,0,1,1,1,2,2,3,3,4]
输出:5, nums = [0,1,2,3,4]
解释:函数应该返回新的长度 5 , 并且原数组 nums 的前五个元素被修改为 0, 1, 2, 3, 4 。不需要考虑数组中超出新长度后面的元素。

        

使用双指针,这题第一遍做过了,i来存数字,j来遍历数组,j != i, i++ 并将j对应的值赋给 i。遍历完成后j会遍历到数组尾部,有几个不同的数字i的下标就是i-1。

代码实现

class Solution {
    public int removeDuplicates(int[] nums) {
        int i = 0;
        for(int j = 1;j < nums.length; j++){
            if(nums[i] != nums[j]){
                i++;
                nums[i] = nums[j];
            }
        }
        return i+1;
    }
}

2. 两数相加

 看他那提示就能看出来其实就是写反过来的两个数相加,只不过我们输出的时候相加的结果也是反过来的 既然要反过来我们就直接反着做,返回值类型是链表也不用考虑位数,那我们直接把链表当前节点进行相加,对10取余的到个位,把这个数加进新链表,十位如果有进位就再当前节点和的基础上加入进位。这个题的关键就是要考虑到进位的问题

代码实现

/**
 * 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 blindNode = new ListNode(0);
        //pre为当前节点的前一个节点
        ListNode preNode = blindNode;
        int curry = 0;//curry来放进位的数
    while(l1 != null || l2 != null || curry != 0){
        int sum = curry;//
        if(l1 != null){//第一个链表
            sum = sum + l1.val;
            l1 = l1.next;
        }
         if(l2 != null){//第二个
            sum = sum + l2.val;
            l2 = l2.next;
        }
        preNode.next = new ListNode(sum % 10);//个位
        curry = sum /10;//十位
        preNode = preNode.next;
    }
    return blindNode.next;
    }
}

猜你喜欢

转载自blog.csdn.net/weixin_57169969/article/details/126727834