测开力扣面试常考简单编程题------手撕

本文详细解析了力扣面试中常见的简单编程题目,包括有效的括号匹配、多数元素查找、两数之和、反转链表、环形链表判断、最大子序列和等问题,涉及数据结构如栈、Map、链表,以及算法思想如二分查找、遍历等。通过实例讲解解题思路和关键点,帮助面试者更好地准备技术面试。
摘要由CSDN通过智能技术生成

测开力扣面试常考简单编程题------手撕

20.有效的括号
题意:找匹配的括号对

class Solution {
   
    public boolean isValid(String s) {
   
        int n=s.length();
        if(n%2!=0){
   
            return false;
        }
        Map<Character,Character> map=new HashMap<>();
        map.put('}','{');
        map.put(']','[');
        map.put(')','(');
        Stack<Character> Stack=new Stack<>();
        for(int i=0;i<n;i++){
   
            char ch=s.charAt(i);
            if(map.containsKey(ch)){
   
                if(Stack.isEmpty() || Stack.pop()!=map.get(ch)){
   
                return false;
                    }else{
   
                        continue;
                    }
            }
            Stack.push(ch);
        }
        if(!Stack.isEmpty()){
   
            return false;
        }
        return true;
    }
}

1 思路:
1)临界情况: 求字符串长度,长度若为奇数,则肯定不存在括号对
2)遍历字符串中的字符
2.1当map中不存在键值时,直接入栈
2.2存在时候,看栈顶元素是否和他匹配,当前栈不为空 (若栈为空,或者不匹配,则返回false)
3)遍历完之后,看栈中是否为空,不为空,则代表有没有匹配完的,返回false;
2 数据结构:
用Map存储括号对,用Stack完成匹配
Map<Character,Character> map=new HashMap<>();
Stack stack=new Stack<>();
3 常用API:
map.containsKey(ch);
map.put(a,b);
map.get(键值)//返回值
stach.push(a);
stack.pop();
stack.peek();//不返回
stack.isEmpty();

169.多数元素
题意:给一个数组,找到数组中元素个数最多(大于数组长度的一半)的数字

class Solution {
   
    public int majorityElement(int[] nums) {
   
        Map<Integer,Integer> res=new HashMap<>();
        for(int i:nums){
   
            if(res.containsKey(i)){
   
                res.put(i,res.get(i)+1);
            }else{
   
                res.put(i,1);
            }
        }
        //依次遍历键值对,找到最大的数字
        Map.Entry<Integer,Integer> max=null;
        for(Map.Entry<Integer,Integer> i:res.entrySet()){
   
            if(max==null || i.getValue()>max.getValue()){
   
                max=i;
            }
        }
        return max.getKey();
    }
}
class Solution {
   
    public int majorityElement(int[] nums) {
   
        Arrays.sort(nums);
        return nums[nums.length/2];
    }
}

1 思路1:
1)对数组进行排序,然后找到中间的哪个数字即可
缺点:
复杂度较高,不推荐

1 思路2:
1)用HashMap存储键值对,数字-个数
2)遍历HashMap,找到最大值的元素,返回键即可
2 数据结构
HashMap即可
键值对 Map.Entry<Integer,Integer> max=null;
API:
map: 取map中的键值对,map.entrySet(); map.get(i); map.containsKey(i);
Map.Entry<> a : a.getValue() a.getKey()

1 两数之和
题意 给一个数组和target,返回数组中和为target的两个下标(数组中只有一种答案)

class Solution {
   
    public int[] twoSum(int[] nums, int target) {
   
        Map<Integer,Integer> temp=new HashMap<>();
        for(int i=0;i<nums.length;i++){
   
            if(temp.containsKey(target-nums[i])){
   
                return new int[]{
   temp.get(target-nums[i]),i};
            }
            temp.put(nums[i],i);
        }
        return new int[]{
   -1,-1};
    }
}

1 思路:
1)用Map存储遍历过的数组的值和下标
2)如果Map中存在 target-当前元素,那么返回该当前的坐标和(target-当前元素)对应的下标(即存储的下标值)
2 数据结构
Map: 存储的键值对是 数组元素-下标
API:
Map : containsKey();

206 反转链表
题意: 反转一个链表

/**
 * 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 reverseList(ListNode head) {
   
        ListNode pre=null,cur=head,next=head;
        while(cur!=null){
   
            next=cur.next;
            cur.next=pre;
            pre=cur;
            cur=next;
        }
        return pre;
    }
}

注意:
在链表中的走向,最容易出现 cur.next=pre; cur=cur.next;这是一个环形的链表;这时候需要借助一个temp节点,保存next
1 思路:
1)1-2-3-4-5-null 可以创建一个 pre =null 再改变指针的指向
2)pre = null cur=head,next=head
3) 当 cur不是空的时候
3.1)保存next=cur.next;
3.2) cur.next=pre,pre=cur,cur=next
3.3) 返回 pre (因为cur 在 null上)
2 数据结构
链表节点 pre cur next
注意先后顺序和是否为空

141 环形链表
题意: 判断链表中是否有环,返回布尔类型

/**
 * Definition for singly-linked list.
 * class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */
public class Solution {
   
    public boolean hasCycle(ListNode head) {
   
        Set<ListNode> temp=new HashSet<>();
        ListNode cur=head;
        while(cur!=null){
   
            if(!temp.add(cur)){
   
                return true;
            }
            temp.add(cur);
            cur=cur.next;
        }
        return false; 
    }
}

1 思路:
1)遍历链表节点(当前节点不为空时候),若当前节点不能添加进Set,就代表有相同的节点,返回true
2) 否则返回false;
2 数据结构
环形链表必定有一个相交的节点,即重复的节点,用Set结构,看是否能添加进去
API:
Set : set.add(i);//返回的是boolean类型

53 最大子序列和
题意: 给个数组,求数组中连续的子序列和的最大值

class Solution {
   
    public int maxSubArray(int[] nums) {
   
        int max=nums[0];
        for(int i=1;i<nums.length;i++){
   
            nums[i]+=Math.max(0,nums[i-1]);
            max=Math.max(max,nums[i]);
        }
        return max;
    }
}

1 思路:
1)遍历时,从索引1开始,(求和)当前的数+前一个数的最大值(0或者大于0的本身,才有相加的意义)
2)求最大值,当前的最大值max和更新后的num[i]中的更大的一个数
2 数据结构
本题是数学题,主要看思路
未用到 API Math.max();

83 删除排序链表中的重复节点
题意:链表中有重复的节点,删除链表重复的节点

/**
 * 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 deleteDuplicates(ListNode head) {
   
        ListNode temp=head;
        while(temp!=null && temp.next!=null){
   
            if(temp.val==temp.next.val){
   
                temp.next=temp.next.next;
            }else{
   
                temp=temp.next;
            }
        }
        return head;

    }
}

注意: 一条语句错了,很容易逻辑错误,面试不要单独领出来说,注意即可
1 思路:
1)定义一个cur指针 cur和cur.next比较,如果相等,则cur.next=cur.next.next;否则正常指向下一个
2)返回head即可
2 数据结构
注意循环找下一个不相等的链表结点

415 字符串相加
题意: 两个字符串相加,返回字符串

class Solution {
   
    public String addStrings(String num1, String num2) {
   
        int i=num1.length()-1;
        int j=num2.length()-1;
        int add=0;
        StringBuffer sb=new StringBuffer();
        while(i>=0 || j>=0 || add!=0){
   
            int x=i>=0?num1.charAt(i)-'0':0;
            int y=j>=0?num2.charAt(j)-'0':0;
            int sum=x+y+add;
            sb.append(sum%10);
            add=sum/10;
            i--;
            j--;
        }
        sb.reverse();
        return sb.toString();
    }
}

1 思路:
1)双指针,从后往前遍历字符串,并且相加,定义进位
2)如果一个字符串的索引不是>=0,那么取值为0
注意:最后一位还有一个进位,也要相加
2 数据结构
StringBuffer: 变长,可以添加字符
API:
StringBuffer sb.append(),sb.reverse(), sb.tostring()

704 二分查找
题意: 排序数组的二分查找

class Solution {
   
    public int search(int[] nums, int target) {
   
        int left=0,right=nums.length-1;
        while(left<=right){
    //注意边界条件
            int base=(left+right)/2;
            if(target==nums[base]){
   
                return base;
            }else if(target>nums[base]){
   
                left=base+1;
            }else{
   
                right=base-1;
            }
        }
        return -1;
    }
}

1 思路:
1)定义左右索引,如果左<=右 定义Mid索引,targe和中间值arr[mid]比对
2) 如果target小于 中间值,right=mid-1;
如果target大于中间值,left=mid+1;
如果等于中间值, 返回索引
2 数据结构
数组:注意循环和边界条件

232 用栈实现队列
栈是先进后出,队列是先进先出
主要实现四个函数:入队push 出队pop 对顶 peek 为空isEmpty

class MyQueue {
   
	/*
	Stack<Integer> d1=new Stack<>();
    Stack<Integer> d2=new Stack<>();
	*/

    Deque<Integer> d1=new LinkedList<>();
    Deque<Integer> d2=new LinkedList<>();

    /** Initialize your data structure here. */
    public MyQueue() {
   

    }
    
    /** Push element x to the back of queue. */
    public void push(int x) {
   
        d1.push(x);

    }
    
    /** Removes the element from in front of queue and returns that element. */
    public int pop() {
   
        if(d2.isEmpty()){
   
            while(!d1.isEmpty()){
   
                d2.push(d1.pop());
            }
        }
        return d2.pop();

    }
    
    /** Get the front element. */
    public int peek() {
   
        if(d2.isEmpty()){
   
            while(!d1.isEmpty()){
   
                d2.push(d1.pop());
            }
        }
        return d2.peek();
    }
    
    /** Returns whether the queue is empty. */
    public boolean empty() {
   
        return d1.isEmpty() && d2.isEmpty();
    }
}

/**
 * Your MyQueue object will be instantiated and called as such:
 * MyQueue obj = new MyQueue();
 * obj.push(x);
 * int param_2 = obj.pop();
 * int param_3 = obj.peek();
 * boolean param_4 = obj.empty();
 */

1 思路:
1)用两个栈,一个是数字栈,一个是辅助栈;
2) 入队列时候,直接将数字加入到 主栈即可;出队和队顶元素需要从辅助栈中,当辅助栈为空时候,需要将主栈元素移动到辅助栈中;是否为空,必须两个栈都为空才行
2 数据结构
栈: 栈的API都可以用,.push() .pop() .peek() . isEmpty()

160 相交链表
两个链表可能有相交的节点,也可能没有相交的节点

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = n
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值