浅刷一下基础题~
目录
1.二分查找
704. 二分查找 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/binary-search/①题目示例:
②方法解析:(二分法)
class Solution { public int search(int[] nums, int target) { // 避免当 target 小于nums[0] nums[nums.length - 1]时多次循环运算 if (target < nums[0] || target > nums[nums.length - 1]) { return -1; } int left = 0, right = nums.length - 1; while (left <= right) { int mid = left + ((right - left) >> 1);//防止溢出的写法,牢记 if (nums[mid] == target) return mid; else if (nums[mid] < target) left = mid + 1; else if (nums[mid] > target) right = mid - 1; } return -1; } }
2.第一个错误版本
278. 第一个错误的版本 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/first-bad-version/①题目示例:
②方法解析:(二分法的利用)
代码:
/* The isBadVersion API is defined in the parent class VersionControl. boolean isBadVersion(int version); */ public class Solution extends VersionControl { public int firstBadVersion(int n) { int left=0; int right=n; while(left<=right){ int mid=left+((right-left)>>1); if(isBadVersion(mid)){ //如果这次试错在中间,那么第一次出现问题的地方,必然在中间值的前面 right=mid-1; }else{ left=mid+1; } }return left; } }
3.搜索插入位置
②方法解析:(二分法)
本题采用二分法,来找到是否含有target所指的数字,若是含有,返回该下标值,要是不含有,则按顺序大小进行插入,然后返回其下标值
代码:
class Solution { public int searchInsert(int[] nums, int target) { int n = nums.length; int low = 0; int high = n - 1; while (low <= high) { int mid = low + ((high - low)>>1); // 防止溢出 if (nums[mid] > target) { high = mid - 1; } else if (nums[mid] < target) { low = mid + 1; } else { return mid; } } return high+1; } }
4.有序数组的平方
②方法解析一:(双指针法)
因为数组均是按照非递减的顺序进行的排列,所以设定两个指针分别从两端出发,比较两者的平方,将较大值放入新的数组后,大的那个指针前移,继续比较,然后和前面所述一致
代码:
class Solution { public int[] sortedSquares(int[] nums) { int left=0; int right=nums.length-1; int tmp[]=new int[nums.length]; int n=nums.length-1; while(left<=right){ if(nums[left]*nums[left]<nums[right]*nums[right]){ tmp[n--]=nums[right]*nums[right]; right--; }else{ tmp[n--]=nums[left]*nums[left]; left++; } }return tmp; } }
③方法解析二:(暴力求解法)
直接将每个数的平方放入一个同样大小的数组中,然后最后对数组整体直接执行现有的排序算法即可
代码:
class Solution { public int[] sortedSquares(int[] nums) { int []tmp=new int[nums.length]; for(int i=0;i<nums.length;i++){ tmp[i]=nums[i]*nums[i]; } Arrays.sort(tmp); return tmp; } }
5.轮转数组
②方法解析: (进行了三次翻转)
代码:
class Solution { private void reverse(int[] nums, int start, int end) { for (int i = start, j = end; i < j; i++, j--) { int temp = nums[j]; nums[j] = nums[i]; nums[i] = temp; } } public void rotate(int[] nums, int k) { int n = nums.length; k %= n; reverse(nums, 0, n - 1); reverse(nums, 0, k - 1); reverse(nums, k, n - 1); } }
6.移动零
283. 移动零 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/move-zeroes/①题目示例:
②方法解析:(利用补0法)
先将数组中非0元素按从0下标依次放入,注意每放入一个元素,记录加一,当该数组中为0的元素完全放完后,从该记录开始全放0,直到整个数组结束为止
代码:
class Solution { public void moveZeroes(int[] nums) { if(nums==null||nums.length<=1){ return; } int index=0; for(int i=0;i<nums.length;i++){ if(nums[i]!=0){ nums[index]=nums[i]; index++;} } for(int i=index;i<nums.length;i++){ nums[i]=0;} } }
7.两数之和,输入有序数组
②方法解析一:(HashMap方法)
让数组中的元素存入map中,然后用target-轮着遍历这个数组,如果减下来的结果存在于HashMap之中,那么就表明肯定是存在这样的两个值,然后范围他们的下标+1;
代码:
class Solution { public int[] twoSum(int[] nums, int target) { Map<Integer,Integer>map=new HashMap<>(); for(int i=0;i<nums.length;i++){ map.put(nums[i],i); } for(int i=0;i<nums.length;i++){ int m=target-nums[i]; if(map.containsKey(m)){ if(map.get(m)!=i){ return new int[]{i+1,map.get(m)+1}; }}} return new int[]{}; }}
③方法解析二:(双指针法)
由题意,该数组是一个递增类型的数组,因此我们可以利用双指针法两边相加与target来比较大小,如果小于该值那么left++,否则的话就应该是right--;
代码:
class Solution { public int[] twoSum(int[] nums, int target) { int left=0; int right=nums.length-1; while(nums[left]+nums[right]!=target){ if(nums[left]+nums[right]<target){ left++; }else{ right--; } }if(nums[left]+nums[right]==target){ return new int[]{left+1,right+1}; }return new int[]{}; } }
8.反转字符串
344. 反转字符串 - 力扣(LeetCode) (leetcode-cn.com)https://leetcode-cn.com/problems/reverse-string/①题目示例:
②方法解析:
a. 本题是一道可以使用双指针方法,一个指针从前,一个从后,两者通过中间值进行交换即可。
b.为了提高时间效率,我们可以将前后两个指针放入同一个循环。
③代码:
class Solution { public void reverseString(char[] s) { for(int left=0,right=s.length-1;left<=right;left++,right--){ //此处需要注意每个字符是字符类型 char tmp=s[left]; s[left]=s[right]; s[right]=tmp; } }
9.反转字符串中的单词
②方法解析一:(利用数组)
本题我们可以知道是在上一个题的基础上进行加深,我们仍可以将上题的思想作为本题的子部分,而进行解题
a.利用和上题相关知识,将字符串转化为字符串来进行求解。设定两个初始值,当一个在向前走时遇到空字符,就执行reverse将目前的范围进行转换,转换完毕后继续执行下一段直至再次遇到空字符 。
代码如下:
class Solution { public String reverseWords(String str) { char[]s=str.toCharArray(); int a=0; int b=0; while(a<s.length){ if(a<s.length&&s[b]!=' '){ b++; continue; } //这个情况就是b=' ',要想逆转上一个字符串,需要b=b-1; //同时a要指向下一个字符串部分的首位,所以a=a++; reverse(s,a,b-1); a=b++; }//最后将其又转换成字符串的形式 return new String(s); } public void reverse(char[]s,int start,int end){ while(start<=end){ char tmp=s[start]; s[start]=s[end]; s[end]=tmp; start++; end--; } } }
②方法解析二:(利用栈)
我们很容易知道,栈的特点是后进先出,当我们把需要逆置的部分放入之后,再出栈自然已经逆置成功,此处我们再利用StringBuilder来实现字符串的拼接,这样的话整个目的就达到了
代码:
class Solution { public String reverseWords(String s) { StringBuilder sb=new StringBuilder(); Stack<Character>stack=new Stack<>(); int i=0; while(i<s.length()){ //第一步入栈 while(i<s.length()&&s.charAt(i)!=' ' ){ stack.push(s.charAt(i)); i++; }//当i为空时,跳出来,第一个部分结束,进行出栈 while(!stack.isEmpty()){ sb.append(stack.pop()); } while(i<s.length()&&s.charAt(i)==' '){ sb.append(' '); i++; } } return sb.toString(); } }