LeetCode模拟面试题合集

【给定一个整数数组 nums,将该数组升序排列。
示例 1:
输入:[5,2,3,1]
输出:[1,2,3,5]
示例 2:
输入:[5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
提示:
1 <= A.length <= 10000
-50000 <= A[i] <= 50000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/sort-an-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。】

//这道题我采用了快速排序
class Solution {
    //快速排序算法
    public int[] sortArray(int[] nums) {
        queckSort(nums,0,nums.length-1);
        return nums;
    }
    
    public void queckSort(int[] nums,int left,int right){
        if(nums.length==0 || left>right){
            return;
        }
        int base=nums[left]; //定义一个基准数为最左边的数
        int i=left;
        int j=right;
        while(i!=j){ //每一轮排序的终止条件为左边和右边的指针相遇了
            
            //先从右边往左边遍历查找比基准数小的数,一旦找到就先停下
            while(nums[j]>=base && i<j){
                j--;
            }
            
            //再从左边往右边遍历查找比基准数大的数,一旦找到就停下
            while(nums[i]<=base && i<j){
                i++;
            }
            
            //一旦j和i的位置都停下了,说明目标已经确定了,就交互当前j和i位置上的数
            int temp=0;
            temp=nums[i];
            nums[i]=nums[j];
            nums[j]=temp; 
            
        }
        //如果左边和右边的指针相遇了,就交换基准数和当前相遇位置的数
        nums[left]=nums[i];
        nums[i]=base;
        //继续递归调用本方法
        queckSort(nums,i+1,right); //当前i和j相遇位置的右边的那些数组继续这样的操作
        queckSort(nums,left,i-1); //当前i和j相遇位置的左边的那些数组继续这样的操作
    }
}

【leetcode 55:】 给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 从位置 0 到 1 跳 1 步, 然后跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/jump-game
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

//采用贪心算法的思想,这里我大概解释一下贪心算法的思想:
 从问题的某个初始解出发,向给定的目标递归,做一个当时看做是最佳的贪心选择,针对这道题来看,就是目标也就是数字的最末尾,往前看,我每次都找到一个能到达我的解。不断的将问题实例归纳为更小的相似的子问题,并希望通过所做过的局部最优选择产生出一个全部最优解。
class Solution {
    public boolean canJump(int[] nums) {
        //采用贪心算法,从后向前遍历整个数组,找到可以到达最右边的元素的位置,并将该位置记录更新为lastPost最右边的元素
        int lastPost=nums.length-1;
        for(int i=nums.length-1;i>=0;i--){
            
            if(i+nums[i]>=lastPost){
                lastPost=i;
            } 
        }
        
        return lastPost==0;
    }
}

【leetcode 39:】
题目:给定一个无重复元素的数组 candidates 和一个目标数 target ,找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的数字可以无限制重复被选取。
说明:所有数字(包括 target)都是正整数。解集不能包含重复的组合。
示例 1:
输入: candidates = [2,3,6,7], target = 7,
所求解集为:
[
[7],
[2,2,3]
]
示例 2:

输入: candidates = [2,3,5], target = 8,
所求解集为:
[
[2,2,2,2],
[2,3,3],
[3,5]
]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/combination-sum
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

//这道题采用回溯法的思想,具体实现其实就是递归。
//这里我首先将给定的目标数组先进行排序,目的是为了剪枝的时候去掉一些没必要的分支,因为这里的target是不断递减的,每次加入一个元素到结果集中,target目标就会减少,直到target等于0,就说明我们找到了一条路径使得相加为target值,那么我们事先是排好序的(这里假如是按照从小到大的顺序排序的,那么当判断到一个节点的时候,它只要比我们目标target还要大,那么就没有必要往后去试探了这时就要回溯了,因为后面的节点肯定比当前节点还要大)
class Solution {
    List<List<Integer>> list=new  ArrayList<>();
    public List<List<Integer>> combinationSum(int[] candidates, int target) {
        if(candidates==null || candidates.length==0 || target==0){
            return list;
        }
         Arrays.sort(candidates);
        List<Integer> arrays=new ArrayList<>();
        dFs(0,target,candidates,arrays);
        return list;
    }
    
    public void dFs(int start,int target,int[] candidates,List arrays){
        if(target==0){
            list.add(new ArrayList<Integer>(arrays));
        }
        for(int i=start;i<candidates.length && target-candidates[i]>=0;i++){
            arrays.add(candidates[i]);
            dFs(i,target-candidates[i],candidates,arrays);
            arrays.remove(arrays.size()-1);
        }   
    }
}

1 给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。

设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。

注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。

示例 1:

输入: [7,1,5,3,6,4]
输出: 7
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天(股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天(股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。

分析:
     要求最大利润,那么就用每次求得最大利润去替换之前求得的最大利润,这么把整个数组走完,就是求得的最终的最大利润了。
class Solution {
    public int maxProfit(int[] prices) {
        
        if(prices.length==0){
            return 0;
        }
        
        int max=0;
        int min=prices[0];
        
        
        //前i-1天的最大利润 和 (第i天的利润-第i-1天的最小利润) 取最大的
    for(int i=1;i<prices.length;i++){
     
        max=Math.max(max,prices[i]-min);
        min=Math.min(min,prices[i]-max);
        
       
    }  
        return max;
    
    }
}

2
给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

class Solution {
    public static List<List<Integer>> threeSum(int[] nums) {
        List<List<Integer>> ans = new ArrayList();
        int len = nums.length;
        if(nums == null || len < 3) return ans;
        Arrays.sort(nums); // 排序
        for (int i = 0; i < len ; i++) {
            if(nums[i] > 0) break; // 如果当前数字大于0,则三数之和一定大于0,所以结束循环
            if(i > 0 && nums[i] == nums[i-1]) continue; // 去重
            int L = i+1;
            int R = len-1;
            while(L < R){
                int sum = nums[i] + nums[L] + nums[R];
                if(sum == 0){
                    ans.add(Arrays.asList(nums[i],nums[L],nums[R]));
                    while (L<R && nums[L] == nums[L+1]) L++; // 去重
                    while (L<R && nums[R] == nums[R-1]) R--; // 去重
                    L++;
                    R--;
                }
                else if (sum < 0) L++;
                else if (sum > 0) R--;
            }
        }        
        return ans;
    }
}

给定一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?找出所有满足条件且不重复的三元组。

注意:答案中不可以包含重复的三元组。

例如, 给定数组 nums = [-1, 0, 1, 2, -1, -4],

满足要求的三元组集合为:
[
[-1, 0, 1],
[-1, -1, 2]
]

class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
        
     List<List<Integer>> list=new ArrayList();
        
        if(nums==null||nums.length<3){
            return list;
        }
        
       Arrays.sort(nums);//对数字按自然顺序(从小到大排序)排序
        
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0) break;
           if(i>0&&nums[i]==nums[i-1]) continue;
            int left=i+1;
            int right=nums.length-1;
            while(left<right){
            if(nums[i]+nums[left]+nums[right]>0){
                right--;
            }else if(nums[i]+nums[left]+nums[right]<0){
                left++;
            }
            else if(nums[i]+nums[left]+nums[right]==0){
                list.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--;
            }  
        }
        }
        return list;
        
    }
}

判断字符括号字符串是否有效:
解法:采用堆栈.

9:用stack实现queue的效果:
采用两个stack模拟,一个栈用来模拟入栈,还有一个栈用来用来装入第一个栈的数据,只要遇到pop或者peek就让第一个栈中的元素先进入到第二个栈中,用第二个栈的弹栈来模拟出队列的效果。

10 优先队列:
正常进入,按照优先级出。
比如:优先级你可以设置为,按最大的出或者按最小的出,或者按照摸个属性出等等。
应用:比如生活中,重要的事情,放入优先队列中,需要优先做的从优先队列中拿即可。
实现机制:
1 Headp(Binary,Binomial,Fibonacci)
2 Binary Search Tree

下图方式采用二叉堆的大顶堆方式实现,这种方式,父亲节点比左右孩子节点都要大。如果插入一个新的元素,需要重新排列。
在这里插入图片描述
java中优先队列的使用方式实例:

//优先数字,从小到大,也是默认的方式
        Queue<Integer> que2 = new PriorityQueue<Integer>();
        que2.add(11);
        que2.add(2);
        que2.add(14);
        que2.add(5);
        que2.add(7);
        int flag2=1;
        while(que2.size()>0){
            if(flag2==1){
                System.out.print(que2.poll());
                flag2=0;
            }else {
                System.out.print(" " + que2.poll());
            }
        }
        System.out.println();
    }
}


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qq_43557743

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值