【给定一个整数数组 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();
}
}