88合并两个有序数组
给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2,另有两个整数 m 和 n ,分别表示 nums1 和 nums2
中的元素数目。请你 合并 nums2 到 nums1 中,使合并后的数组同样按 非递减顺序 排列。
注意:最终,合并后数组不应由函数返回,而是存储在数组 nums1 中。为了应对这种情况,nums1 的初始长度为 m + n,其中前 m
个元素表示应合并的元素,后 n 个元素为 0 ,应忽略。nums2 的长度为 n 。
- 概述:给你两个数组让你合并,还给你排序了,这种最好的方法就是双指针
class Solution {
public static void merge(int[] nums1, int m, int[] nums2, int n) {
if(nums1==null && nums2==null){
}else if(nums2==null || nums2.length==0){
}else{
int[] str = new int[n+m];
int x=0,y=0,num;
while (x<m || y<n){
if(x==m){
num = nums2[y++];
}else if(y==n){
num = nums1[x++];
}else if(nums1[x] < nums2[y]){
num = nums1[x++];
}else {
num = nums2[y++];
}
str[x+y-1] = num;
}
for(int i=0;i<nums1.length;i++){
nums1[i] = str[i];
}
}
}
}
215数组中的第k个最大元素
给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。
请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。
你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。
- 概述:让你给数组排个序,找出第k大元素,时间复杂度O(n)
3分钟面试式做法
class Solution {
public int findKthLargest(int[] nums, int k) {
Arrays.sort(nums);
return nums[nums.length - k];
}
}
167两数之和Ⅱ
给你一个下标从 1 开始的整数数组 numbers ,该数组已按 非递减顺序排列 ,请你从数组中找出满足相加之和等于目标数 target
的两个数。如果设这两个数分别是 numbers[index1] 和 numbers[index2] ,则 1 <= index1 <
index2 <= numbers.length 。以长度为 2 的整数数组 [index1, index2] 的形式返回这两个整数的下标 index1 和 index2。
你可以假设每个输入 只对应唯一的答案 ,而且你 不可以 重复使用相同的元素。
你所设计的解决方案必须只使用常量级的额外空间。
- 概述:给你一个有数数组,再给你一个数,让你在这数组中找两个数的和等于给的这个数,不能自身与自身相加
- 一般给你排序了都是双指针
暴力解法
class Solution {
public static int[] twoSum(int[] numbers, int target) {
int[] str = new int[2];
for(int i=0;i<numbers.length;i++){
for(int j=0;j<numbers.length;j++){
if(i!=j && numbers[i]+numbers[j]==target){
str[0] = i+1;
str[1] = j+1;
return str;
}
}
}
return str;
}
}
碰撞指针
class Solution {
public static int[] twoSum(int[] numbers, int target) {
int i = 0,j = numbers.length-1;
while (true){
int sum = numbers[i]+numbers[j];
if(i!=j && sum==target){
return new int[]{i+1,j+1};
}else if(sum>target){
j--;
}else if(sum<target){
i++;
}
}
}
}
125验证回文串
如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后,短语正着读和反着读都一样。则可以认为该短语是一个 回文串 。
字母和数字都属于字母数字字符。
给你一个字符串 s,如果它是 回文串 ,返回 true ;否则,返回 false 。
- 概述:给你一个字符串,让你将数字和字母留下,字母大写就换成小写,然后判断是不是回文串
- 做法:将字符串全部按照指定格式存入string builder中,然后判断
class Solution {
public static boolean isPalindrome(String s) {
StringBuilder sb = new StringBuilder();
int len = s.length();
for(int i=0;i<len;i++){
char ch = s.charAt(i);
if(ch>=97 && ch<=122){
sb.append(ch);
}
if(ch>=48 && ch<=57){
sb.append(ch);
}
if(ch>=65 && ch<=90){
ch += 32;
sb.append(ch);
}
}
StringBuilder sb2 = new StringBuilder(sb).reverse();
return sb.toString().equals(sb2.toString());
}
}
344反转字符串
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
- 概述:给你一个字符数组,让你反过来输出
- 做法:最朴素的解法
class Solution {
public static void reverseString(char[] s) {
if(s==null || s.length==0){
return;
}
for(int i=0,j=s.length-1;i<j;i++,j--){
char ch = s[i];
s[i] = s[j];
s[j] = ch;
}
}
}
345反转字符串中的元音字母
**给你一个字符串 s ,仅反转字符串中的所有元音字母,并返回结果字符串。
元音字母包括 ‘a’、‘e’、‘i’、‘o’、‘u’,且可能以大小写两种形式出现。
- 概述:给你一个字符串,让你将其中的原因字母反转,然后输出反转后的字符串
- 做法:判断是否原因字母,双指针进行修改
时间很快
class Solution {
public static String reverseVowels(String s) {
if(s==null || s==""){
return null;
}
char[] str = s.toCharArray();
for(int i=0,j=str.length-1;i<j;){
if(str[i] == 'a' || str[i] == 'e' || str[i] == 'i' || str[i] == 'o' || str[i] == 'u' ||
str[i] == 'A' || str[i] == 'E' || str[i] == 'I' || str[i] == 'O' || str[i] == 'U'){
if((str[j] == 'a' || str[j] == 'e' || str[j] == 'i' || str[j] == 'o' || str[j] == 'u')
|| str[j] == 'A' || str[j] == 'E' || str[j] == 'I' || str[j] == 'O' || str[j] == 'U'){
char ch = str[i];
str[i] = str[j];
str[j] = ch;
i++;
j--;
}else{
j--;
}
}else{
i++;
}
}
return new String(str);
}
}
内存减小,时间增大
class Solution {
public static String reverseVowels(String s) {
if(s==null || s==""){
return null;
}
char[] str = s.toCharArray();
for(int i=0,j=str.length-1;i<j;){
if(click(str[i])){
if(click(str[j])){
char ch = str[i];
str[i] = str[j];
str[j] = ch;
i++;
j--;
}else{
j--;
}
}else{
i++;
}
}
return new String(str);
}
public static boolean click(char ch) {
return "aeiouAEIOU".indexOf(ch) >= 0;
}
}
11盛水最多的容器
给定一个长度为 n 的整数数组 height 。有 n 条垂线,第 i 条线的两个端点是 (i, 0) 和 (i, height[i]) 。
找出其中的两条线,使得它们与 x 轴共同构成的容器可以容纳最多的水。
返回容器可以储存的最大水量。
说明:你不能倾斜容器。
- 概述:给你一个数组让你找面积最大的地方
- 做法:可暴力双循环解但是一般会超时,用点技巧可以通过
- 建议:双指针
暴力解法
class Solution {
public static int maxArea(int[] height) {
int sum = 0;
int num,flag;
for(int i=0;i<height.length;i++){
if(height[i]<1){continue;}
for(int j=sum/height[i]+i;j<height.length;j++){
flag = height[i]<height[j]?height[i]:height[j];
num = (j-i)*flag;
if(num>sum){
sum = num;
}
}
}
return sum;
}
}
双指针
class Solution {
public static int maxArea(int[] height) {
int sum = 0;
for(int i=0,j=height.length-1;i<j;){
int flag;
flag = (j-i)*Math.min(height[i],height[j]);
if(flag>sum){
sum = flag;
}
if(height[i]<height[j]){
i++;
}else{
j--;
}
}
return sum;
}
}