2023-02-26-JAVA刷题账目表

待处理

周赛 6242

class Main{
    public static void main(String[] args) {

        Solution s = new Solution();
    }
}

刷题中常用的Java方法

常见的数据类型

//  1.  char 和String
//        char s1="n";错误,char需要单引号
//		char s1='nl';错误,char是一个字符
        char s1='n';正确
//        String s2='asdasd'; 错误,string 是双引号
        String s2="asdasdasd";正确
//  2. long型
       /*
        系统不会自动将99999999999999当做long处理,而是当做int处理,而本身99999999999999超出int范围,故赋值失败
         */
        //long num1=99999999999999;
        /*
        如果希望系统将99999999999999当做long处理,则需要在常量值后面添加l或L后缀
         */
        long num1=99999999999999L;
//  3. float型
如果希望系统将1.5当做float处理,则需要在常量值后添加f或F后缀
float f2=1.5f;

常见的转义字符

转义字符 说明
\b 退格符
\n 换行符
\r 回车符
\t 制表符
\” 双引号
\‘ 单引号

自增操作i++

        //格式1:运算符在操作数左边
        /*
        先将i自增1,然后赋值给j
         */
        int i = 10;
        int j = ++i;
        System.out.println("i=" + i + "\tj=" + j);//i=11 j=11
        //格式2:运算符在操作数右边
        /*
        现将i本身的值取出来放在操作数栈中,然后i自增1,再用操作数栈中的10赋值给j
         */
        int i = 10;
        int j = i++;
        System.out.println("i=" + i + "\tj=" + j);//i=11 j=10
        //格式3:混合运算
        int i = 10;
        int j = (i++) + (++i) * (i++);//j=10+12*12
        System.out.println("i=" + i + "\tj=" + j);//i=13,j=154

创建string

//方式一:通过字符串常量的方式 
String str1 = "joshua317"; 
//方式二:通过new一个对象方式创建 
String str2 = new String("joshua317"); 

数组操作

创建int[] nums

//创建int[] nums 
int[] nums = {1,3,5,2,5,1,2,3,4,5,7};

元素插入数组操作---add

public class Solution  {

    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(0);//插入第一个元素
        list.add(1);
        System.out.println(list);//打印list数组
        System.out.println(list);
        }

    }

System.arraycopy函数

//System.arraycopy(src, srcPos, dest, destPos, length);
public class Solution  {
    public static void main(String[] args) {
        // 源数组
        int[] src = new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
        // 目标数组
        int[] dest = new int[10];
        System.out.println("cope前:" + Arrays.toString(dest));//cope前:[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
//		copy(src, 2, dest, 5, 4);
        System.arraycopy(src, 2, dest, 5, 4);
        System.out.println("cope后:" + Arrays.toString(dest));//cope后:[0, 0, 0, 0, 0, 3, 4, 5, 6, 0]
    }
}

一些稀奇古怪的省略

for(;;)

/*while(true) 和for(;;)是一样的
for(;;)
即不设初值,不判断条件,循环变量不增值.
无终止的循环。
那个程序会死循环
可以在循环中添加一个语句来说明这个问题*/
for(;;){
System.out.println("aa");
}
//会一直输出 字符串 aa

a&=b

“&=”是JavaScript赋值运算符,意思是将左边变量与右操作数的值按位与。如,a&=b,相当于a=a&b。等号“=”就是赋值用的。而&是JavaScript的位运算符,是按位与的意思,
就是当两个操作数的相应位都为1时,该位的结果为1,否则为0。

? :

条件运算符( ? : )也称为 “三元运算符”或“三目运算符”。语法形式:布尔表达式 ? 表达式1 :表达式2。
运算过程:如果布尔表达式的值为 true ,则返回 表达式1的值,否则返回 表达式2 的值。

数组:

2022-11-19----

二分法

E367
class Solution {
    public boolean isPerfectSquare(int num) {
        int left=0;
        int right=num;
        while (left<right){
            int mid=left+((right-left)>>1);
            long square=(long)mid *mid;
            if (square<num){
                left=mid+1;
            }else if (square>num){
                right=mid-1;
            }else {
                return true;
            }
        }
        if (left*left==num){
            return true;
        }else {

            return false;
        }
//        return false;
    }
}
// E35
class Solution {
    public int searchInsert(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while(left<=right){
            int mid=((right-left)>>1)+left;
            if(target==nums[mid]){
                return mid;
            } else if (nums[mid]<target) {
                left=mid+1;
            }else{
                right=mid-1;
            }

        }
	return left;
    }
}
// M704;

class Solution {

    public int search(int[] nums, int target) {
        int left=0;
        int right=nums.length-1;
        while(left<right){
            int middle=left+((right-left)>>1);
            if(nums[middle]<target){
                left=middle+1;
            }else if(nums[middle]==target){
                right=middle;
            }else{
                right=middle-1;
            }

        }
        if(nums[left]==target){
        	return left;
        }else{
        	return -1;
        }
        
    }
}
package com.sue.M34;

/**
 * @author Anthony
 * @create 2022-11-21 17:59
 */
class Solution {
    public int[] searchRange(int[] nums, int target) {
        int l = nums.length;
        if (l == 0) {
            return new int[]{-1, -1};
        }
        int firstPosition = findFirstPosition(nums, target);
        if (firstPosition == -1) {
            return new int[]{-1, -1};

        }
        int lastPosition = findLastPosition(nums, target);
        return new int[]{firstPosition, lastPosition};

    }

    private int findFirstPosition(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;
        while (left < right) {
            int middle = left + ((right - left) >> 1);
            /*
            1先小于 left=middle+1
            2等于时,middle=left
            3小于时,right=middle-1
            */
            if (nums[middle] < target) {
                left = middle + 1;
            } else if (nums[middle] == target) {
                right = middle;
            } else {
                right = middle - 1;
            }
        }
        /*循环完之后,left可能落在target,也可能 left > right都没找到 所以返回-1
        
        */
        if (nums[left] == target) {
            return left;
        } else {
            return -1;
        }

    }

    private int findLastPosition(int[] nums, int target) {
        int left = 0;
        int right = nums.length - 1;

        while (left < right) {
            int middle =  ((left + right +1) >> 1);//向上取整的精妙之处需要体会
            /*
            1先小于 left=middle+1
            2等于时,middle=left
            3小于时,right=middle-1
            */
            if (nums[middle] < target) {
                left = middle + 1;
            } else if (nums[middle] == target) {
                left = middle;
            } else {
                right = middle - 1;
            }
        }
        return left;

    }
}

class Main{
    public static void main(String[] args) {
        int []nums =   {5,7,7,8,8,10};
        int target = 8;
        Solution s = new Solution();
        int[] res = s.searchRange(nums, target);
//        System.out.println(res);
        for(int a:res)System.out.println(a);//数组输出的格式for
    }

}
E69 可用二分法再做一遍

二分法搜索插入位置

/*
给定一个排序数组和一个目标值,在数组中找到目标值,并返回其索引。如果目标值不存在于数组中,返回它将会被按顺序插入的位置。
*/
class Solution {
    public int searchInsert(int[] nums, int target) {
    	int left=0,right=nums.length;
    	while(left<right){
			int mid=(right-left)/2+left;
			if(nums[mid]==target){
				return mid;
			}else if(nums[mid]<target){
				left=mid+1;
			}else{
                right=mid;
            }
	    }
        return left;
	    }
}

27.移除元素

//E27
class Solution {
    public int removeElement(int[] nums, int val) {
        int l = nums.length;
        int left = 0;

        for (int right = 0; right < l; right++) {
            if (nums[right] != val) {
                nums[left] = nums[right];
                left++;
            }
        }
        return left;
    }
}

class Solution1{
    /*
    双指针
     */
    public int removeElement(int[] nums, int val) {
        int left=0;
        int right=nums.length-1;
        while (left<=right){
            if (nums[left]==val){
                nums[left]= nums[right];
                right--;
            }else {
                left++;
            }

        }
        return left;
    }


}
  • 26.删除排序数组中的重复项
    class Solution1{
        public int removeDuplicates(int[] nums) {
            int l=nums.length;
            int q=0;
    
            for (int p=1;p<l;){
                if (nums[p]==nums[q]){
    
                    p++;
                }else {
                    nums[q+1]=nums[p];
                    q++;
                    p++;
                }
            }
            return q+1;
        }
    }
    
    283.移动零
    class Solution {
    //    public void moveZeroes(int[] nums) {
    //        if (nums==null){
    //            return;
    //        }
    //        int j=0;
    //        for (int i=0;i<nums.length;i++){
    //            if (nums[i]!=0){
    //                int temp=nums[i];
    //                nums[i]=nums[j];
    //                nums[j++]=temp;
    //            }
    //        }
    //    }
        public void moveZeroes(int[] nums)  {
            if (nums==null){
                return;
            }
            int j=0;
            for (int i=0;i<nums.length;i++){
                if (nums[i]!=0){
                    if (i>j){
                        nums[j]=nums[i];
                        nums[i]=0;
                    }
                    j++;
                }
            }
    
        }
    }
    
    //844.比较含退格的字符串 
    
    //977.有序数组的平方
    

59.螺旋矩阵II

54.螺旋矩阵
剑指Offer 29.顺时针打印矩阵

滑动窗口

//209.长度最小的子数组
class Solution{
    public int minSubArrayLen(int target, int[] nums) {
        int n= nums.length;
        if (n==0){
            return 0;
        }
        int ans=Integer.MAX_VALUE;
        int start=0;
        int end=0;
        int sum=0;
        while (end<n){
            sum=sum+nums[end];
            while (sum>=target){
                ans=Math.min(end-start+1,ans);//更新ans 因为sum还是>=target,且start++了。
                sum=sum-nums[start];
                start++;
            }
            end++;
        }
        return  ans==Integer.MAX_VALUE?0:ans;//针对的是target=11 nums=[1,1,1,1]
    }
}
//904.水果成篮(opens new window)
class Solution {
    public int totalFruit(int[] fruits) {
        int n=fruits.length;
        HashMap<Integer, Integer> cnt = new HashMap<>();
        int left=0;
        int ans=0;
        for (int right =0;right<n;++right){
            cnt.put(fruits[right],cnt.getOrDefault(fruits[right],0)+1);
            while (cnt.size()>2){
                cnt.put(fruits[left],cnt.get(fruits[left])-1);
                if (cnt.get(fruits[left])==0){
                    cnt.remove((fruits[left]));
                }
                ++left;    
            }
            
            ans=Math.max(ans,right-left+1);
        }
        return ans;

    }
}
//76.最小覆盖子串
很难

双指针

/*
M713
*/
class Solution {
    public int numSubarrayProductLessThanK(int[] nums, int k) {
        if (k <= 1)
            return 0;
        int n = nums.length, ans = 0, prod = 1, left = 0;
        for (int right = 0; right < n; ++right) {
            prod *= nums[right];
            while (prod >= k) // 不满足要求,把左端点值除掉,然后left++,while继续判断
                prod /= nums[left++];
            ans += right - left + 1;//此时的子数组个数为right-left+1,如right=left时,为1
        }
        return ans;
    }
}

杂项

//977.有序数组的平方
class Solution {
    public int[] sortedSquares(int[] nums) {
		int [] ans=new int[nums.length];
		for (int i=0;i<ans.length ;i++ ) {
			ans[i]=nums[i]*nums[i];
		}

		Arrays.sort(ans);
		return ans;
    }
}

链表

哈希表

Map接口的方法

//	1.hashMap的创建
Map<Integer, Integer> map = new HashMap<Integer, Integer>();//<1,2>位置1、2可以是String、List、Integer、

new HashMap<Integer, String>() {{ 
	put("0","成功");
}};
//	2.添加操作
void put(key,value);//如果key不在map中,则会新添加
void putAll(Map,map);//将另一个map中的键值对添加到当前Map集合中,如果key相同,则会覆盖原有value
//	3.删除操作
void clear();//清空当前map集合
Object remove(Object key)//根据指定的key从当前map中删除一对映射关系
//	4.查询操作
Object get(Object key)//根据指定的key从当前map中查找其对应的value
boolean containsKey(Object key)//判断在当前map中是否存在指定的key
boolean containsValue(Object value)//判断在当前map中是否存在指定的value
Object getOrDefault(Object key, V defaultValue)//意思就是当Map集合中有这个key时,就使用这个key对应的value值,如果没有就使用默认值defaultValue
boolean isEmpty()//判断当前map是否为空
//	5.其他操作
int size()//获取当前map中(key,value)的键值对数。

    

字符串

双指针法

栈与队列

//E844
   
//M11
class Solution {
    public int maxArea(int[] height) {
        int left=0;
        int right=height.length-1;
        int ans=0;
        while (left<right){
            // int area = (right - left) * Math.min(height[left], height[right]);
            int area=(right-left)*Math.min(height[left],height[right]);
            ans=Math.max(ans,area);
            if (height[left]<height[right]){
                left++;
            }else {
                right--;
            }
        }
        return ans;
    }
}

二叉树

回溯&递归

贪心算法

动态规划

斐波那契数列(滚动数组)

斐波那契数的边界条件是 F(0)=0 和 F(1)=1。当 n>1 时,每一项的和都等于前两项的和,因此有如下递推关系:

F(n)=F(n−1)+F(n−2)

由于斐波那契数存在递推关系,因此可以使用动态规划求解。动态规划的状态转移方程即为上述递推关系,边界条件为 F(0)和 F(1)。

根据状态转移方程和边界条件,可以得到时间复杂度和空间复杂度都是 O(n)的实现。由于 F(n) 只和 F(n−1) 与 F(n−2)有关,因此可以使用「滚动数组思想」把空间复杂度优化成 O(1)。如下的代码中给出的就是这种实现。

/*
边界条件是 F(0)=0 和 F(1)=1
递推关系是fn=fn-1+fn-2

根据状态转移方程和边界条件,可以得到时间复杂度和空间复杂度都是 
O(n) 的实现。由于 F(n) 只和 F(n−1)
与 F(n−2)有关,因此可以使用「滚动数组思想」把空间复杂度优化成 
O(1)。如下的代码中给出的就是这种实现。

*/
//E509
class Solution {
    public int fib(int n) {
    	if (n<2) {
    		return n;
    	}
    	int p=0,q=0,r=1;
    	for (int i=2;i<=n ;i++ ) {
    		p=q;//0
    		q=r;//1
    		r=p+q;//1
    	}
    	return r;
    }
}
//E746
class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int[] dp = new int[n + 1];
        dp[0] = dp[1] = 0;
        for (int i = 2; i <= n; i++) {
            dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
        }
        return dp[n];
    }
}

//优化版 使用滚动数组的思想,将空间复杂度优化到 O(1)。
class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        int prev = 0, curr = 0;
        for (int i = 2; i <= n; i++) {
            int next = Math.min(curr + cost[i - 1], prev + cost[i - 2]);
            prev = curr;
            curr = next;
        }
        return curr;
    }
}

单调栈

按照LeetCode标签记录

链接 https://programmercarl.com/

posted @ 2023-06-29 17:41  苏春雨1024  阅读(21)  评论(0)    收藏  举报