LeetCode

博主是从简单开始做

  • Reverse Integer(反转数字)

    Integer.MIN_VALUE,Integer.MAX_VALUE,表示int的最大和最小范围,使用long型防止溢出。

 

 

  • Palindrome Numb(回文数)

回文数是反着和正着都相同的数,采用恢复一半的数字来判断是否为回文数,列如1221,恢复后半段1221的21为12,与前半段进行比较,如果相同则为回文数,当我们将数字除以10,并将倒数乘以10,当原始数字小于倒数时,这意味着我们已经处理了一半数字的数字,当数字长为奇数时,把恢复数再除以10,奇数中间可以不做比较

额外补充:str.reverse()字符串反转

 

int i = Integer.parseInt(str);String转intString转int
String s = String.valueOf(i); String s = Integer.toString(i) int转Stringint转String
 

 

 

  • Roman to Integer(罗马数字转换为整型)
  • class Solution {
        public int romanToInt(String s) {
    		int []nums=new int[s.length()];
    		for(int i=0;i<s.length();i++){
    			if(s.charAt(i)=='I'||s.charAt(i)=='i')
    				nums[i]=1;
    			if(s.charAt(i)=='V'||s.charAt(i)=='v')
    				nums[i]=5;
    			if(s.charAt(i)=='X'||s.charAt(i)=='x')
    				nums[i]=10;
    			if(s.charAt(i)=='L'||s.charAt(i)=='l')
    				nums[i]=50;
    			if(s.charAt(i)=='C'||s.charAt(i)=='c')
    				nums[i]=100;
    			if(s.charAt(i)=='D'||s.charAt(i)=='d')
    				nums[i]=500;
    			if(s.charAt(i)=='M'||s.charAt(i)=='m')
    				nums[i]=1000;
    		}
    		int sum=0;
    		for(int i=0;i<s.length()-1;i++){
    			if(nums[i]<nums[i+1])
    				sum=sum-nums[i];
    			else
    				sum=sum+nums[i];
    		}
    	   return sum+nums[s.length()-1];
    	}
    
    
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		Solution w=new Solution();
    		System.out.println(w.romanToInt("V"));
    	}
    }

 

  • 新建一个s.length()的数组nums[]来保存每个罗马数字对应的整型数字,通过charAT方法获得s中的每个字母。

 

 

  • Longest Common Prefix 最长的通用前缀
public class WW {
	public String longestCommonPrefix(String[] strs) {
		if(strs.length==0)
			return "0";
		String p=strs[0];
		for(int i=1;i<strs.length;i++)
			while(strs[i].indexOf(p)!=0)
			{
				p=p.substring(0, p.length()-1);
				if(p.isEmpty())
					return "";
			}		
		return p;
		
	}
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		WW w=new WW();
		String []strs={"abc","abcde","ab"};
		System.out.println(w.longestCommonPrefix(strs));
	}

}

 

  • strs[i].indexOf(p),通过indexof方法判断strs[i]中是否有p,如果有则返回0,如果没有则返回-1,进去while函数,通过substring方法裁剪p,裁剪后再通过indexof方法与strs[i]进行判断。如果裁剪到0还是没有返回0,则返回“ ”说明没有相同的前缀。

 

  • Valid Parentheses
    public class WW {
    	public boolean isValid(String s) {
    		Stack<Character> stack = new Stack<>();
    	    for (int i = 0; i < s.length(); i++) {
    	        switch (s.charAt(i)) {
    	            case '(':
    	                stack.push('(');
    	                break;
    	            case '{':
    	                stack.push('{');
    	                break;
    	            case '[':
    	                stack.push('[');
    	                break;
    	            case ')':
    	                if (stack.size() == 0 || stack.pop() != '(')
    	                   return false;
    	                break;
    	            case '}':
    	                if (stack.size() == 0 || stack.pop() != '{')
    	                    return false;
    	                break;
    	            case ']':
    	                if (stack.size() == 0 || stack.pop() != '[')
    	                    return false;
    	                break;
    	        } }
    	    return stack.isEmpty();
    	}
    	public static void main(String[] args) {
    		// TODO 自动生成的方法存根
    		WW w=new WW();
    		System.out.println(w.isValid(""));
    	}
    
    }
  • 创建一个stack,通过switch把({[把push进栈中,然后让)}]与栈顶pop后进行比较,如果不相等,返回false,同时注意栈的长度。最后判断栈是否为空。
     

 

 

 

  • 合并两个有序的链表
  • 	    private class Node{
    	        private int data;//每个节点的数据
    	        private Node next;//每个节点指向下一个节点的连接
    	        
    	        public Node(int data){
    	            this.data = data;
    	        }
    	    }
    
      public Node mix(Node l,Node l2){
    	    	if(l==null){
    	    		return l2;
    	    	}else if(l2==null){
    	    		return l;
    	    	}
    	    	Node l3=null;
    	    	if(l.data<=l2.data){
    	    		l3=l;
    	    		l3.next=mix(l.next,l2);
    	    	}else{
    	    		l3=l2;
    	    		l3.next=mix(l,l2.next);
    	    	}
    			return l3;
    	    }

 

  • 采用递归的算法,l与l2数据比较,如果l小则把该结点赋给l3,然后才有递归,比较l1的下一个数据与l2当前的数据比较谁大谁小
    l3.next=mix(l.next,l2);

 

 

删除排序数组中的重复项

因为题目说删除重复下,所以想到的是用hashset的无序性,用HashSet来保存num数组,来把那些重复项删除,在eclipse上能够运行,但移到LeetCode就无法通过了,原因 一直也搞不懂

	public int Remove(int []num){
		/*HashSet<Integer> list=new HashSet<>();
		for(int i=0;i<num.length;i++){
			list.add(num[i]);
		}
		int len=list.size();
		System.out.println("len: "+len);
		Iterator<Integer>it=list.iterator();
		while(it.hasNext()){
			System.out.println(it.next());
		}
}*/

官方的解答是用了双指针,当num[i]!=num[j]时,i++,同时把num[j]赋值给num]i],覆盖重复项,最后返回i+1即数组的长度

if(num==null)
			return 0;
		int i=0;
		for(int j=1;j<num.length;j++){
			if(num[j]!=num[i]){
				i++;
				num[i]=num[j];
			}
		}
		return i+1;

移除元素

移除元素的方法移除数组中重复项的方法相同

public void remove(int nums[],int num){
		int i=0;
		for(int j=0;j<nums.length;j++){
			if(nums[j]!=num){
				nums[i]=nums[j];
				i++;
			}
		}
		for(int w=0;w<i;w++){
			System.out.println(nums[w]);
		}
	}
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Test27 t=new Test27();
		int nums[]={3,2,2,2,3};
		t.remove(nums, 3);
	}

实现strSTR

使用字符串中的indexOf方法即可

public void strStr(String h,String n){
		if(n==null){
			System.out.println(0);
		}
		int num=h.indexOf(n);
		System.out.println(num);
	}
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Test28 t=new Test28();
		String h="aaaaaa";
		String n="bba";
		t.strStr(h, n);
	}

 

搜索插入位置

这个方法很暴力,效率低,看代码都能看懂,看了别人的才知道还有个二分查找法,唉,数据结构太差了

public int find(int[] nums,int num){
		int temp=0;
		if(nums.length==1){
			for(int i=0;i<nums.length ;i++){
				if(nums[i]<num){
					temp=i+1;
				}else{
					temp=i;
				}
			}
		}else{
			for(int i=0;i<nums.length-1;i++){
				if(nums[i]==num){
					temp=i;
					break;
				}			
				else if(nums[i]<num&&num<=nums[i+1]){
					temp=i+1;
					break;
				}else if(num>nums[nums.length-1]){
					temp=nums.length;
				}else if(num<nums[i]){
					temp=0;
				}
			}
		}
		return temp;
	}
	public static void main(String[] args) {
		// TODO 自动生成的方法存根
		Test35 t=new Test35();
		int[]nums={1,2,4,6,7,9,11};
		System.out.println(t.find(nums, 7));
		
	}

二分查找法

	int L=0;
		int R=nums.length-1;
		while(L<=R){
			int mid=L+(R-L)/2;
			if(nums[mid]==num)
				return mid;
			else if(nums[mid]>num){
				R=mid-1;
			}else{
				L=mid+1;
			}
		}
		return L;

报数

public String CountAndSay(int n){
		String str="1";
		String result="";
		int sum=1;
		if(n==1){
			return str;
		}
		if(n==2){
			str="11";
			return str;
		}
		str="11";
		for(int i=2;i<n;i++){
			for(int j=0;j<str.length();j++){
				if(j!=str.length()-1&&str.charAt(j)==str.charAt(j+1)){
					sum++;
					continue;
				}else if(j==str.length()-1&&str.charAt(j)==str.charAt(j-1)){
					result=result+String.valueOf(sum)+str.charAt(j);
					sum=1;
				}else{
					result=result+String.valueOf(sum)+str.charAt(j);
					sum=1;
				}
			}
			str=result;
			result="";
		}
		return str;

 

  • 最大子序和

这道题一开始想错了方向,想了半天都没解决,最后才明白其实只需要数组每项加起来,负数不加就可以了

public int maxSubArray(int num[]){
		int max[]=new int[num.length];
		int maxx=num[0];
		max[0]=maxx;
		for(int i=1;i<num.length;i++){
			max[i]=max[i-1]>0?max[i-1]+num[i]:num[i];
			maxx=Math.max(max[i],maxx);
		}
		return maxx;
	}

最后一个单词的长度

用split把带有空格的字符串分割成数组,然后取数组的最后一个转换成char数组,最后算出char数组的长度

还要判断字符串是否有单词还是只有空格

 

public int lengthOfLastWord(String str){
		char[]ch=null;
		String[]strr=str.split(" ");
		if(str==" "||str==""||strr.length==0){
			return 0;
		}else{			
			ch=strr[strr.length-1].toCharArray();
		}
		
		
		return ch.length;
		

加一

用了个很暴力的方法,但在LeetCode通过不了。。先把数组转换成数字加一,然后再转换成数组,为了任意精度,选用了大数值

/*StringBuffer sb=new StringBuffer();
		for(int i=0;i<num.length;i++){
			sb.append(num[i]);
		}
		String str=sb.toString();
		BigInteger big=new BigInteger(str);
		BigInteger big2=new BigInteger("1");
		str=String.valueOf(big.add(big2));
		num=new int[str.length()];
		for(int i=0;i<str.length();i++){
			num[i]=Integer.parseInt(str.substring(i, i+1));
		}
		return num;*/

下面这个方法LeetCode可以通过

 for(int i=num.length-1;i>=0;i--){
			 if(num[i]==9){
				 num[i]=0;
			 }else{
				 num[i]++;
				 return num;
			 }			 
		 }
		int[]nums=new int[num.length+1];
		 nums[0]=1;
		 return nums;
		 

x的平方根

	public int mySqrt(int x){
		int num=(int) Math.sqrt(x);
		return num;
	}

爬楼梯

运用递归来解决这个问题,也可以找出规律用循环,爬n步楼梯,可以想象成是在n-1层爬了一节楼梯,也可以是在n-2层爬了两节楼梯,以此来递归算出有多少种方法(这道题一开始没想到用递归,想找规律,结果算错了,规律一直没找到,最后上网查了才发现递归如此好用)

	 public int climbStairs(int n){
		 if(n==1)
			 return 1;
		 if(n==2)
			 return 2;
		 int nums[]=new int[n+1];
		 nums[1]=1;
		 nums[2]=2;
		 climb(nums,n);
		return nums[n];
		 
	 }
	private void climb(int[]nums, int n) {
		// TODO 自动生成的方法存根
		int a=n-1;
		int b=n-2;
		if(a>2&&nums[a]==0)
			climb(nums,a);
		if(b>2&&nums[b]==0)
			climb(nums,b);
		nums[n]=nums[a]+nums[b];
	}

删除排序列表中重复的元素

简单的链表删除就可以实现,但是要注意空链表的条件,通过刷题发现我对数据结构的掌握很不牢固

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode deleteDuplicates(ListNode n) {
        if(n==null||n.next==null)
	    		return n;
        ListNode node=n;
	    ListNode node2=n.next;	    	
	    	while(node2!=null){
	    		if(node.val==node2.val){
	    			node.next=node2.next;
	    			node2=node2.next;
	    		}else{
	    			node=node.next;
	    			node2=node2.next;
	    		}
	    	}
	    	return n;
    }
}

合并两个有序数组

先用copyOf把数组一的长度扩大到m+n,然后数组一和数组二从最后的数开始比较(因为是有序的,所有最后的数最大),大的数放在扩大后的数组一的最后一位,一下代码在eclipse能够通过,但在LeetCode就不能通过了,也不知道为什么。

 public void merge(int[] nums1, int m, int[] nums2, int n){
		 int temp= m+n;
		nums1=Arrays.copyOf(nums1, temp);
		 --temp;
		 --m;
		 --n;
		 while(m>=0&&n>=0){
			nums1[temp--]=nums1[m]>nums2[n]?nums1[m--]:nums2[n--];
		 }
		 while(n>=0){
			 nums1[temp--]=nums2[n--];
		 }
		 for (int i : nums1) {
			System.out.print(i+" ");
		}

下面的代码在LeetCode就能够通过。。。

 public void merge(int[] nums1, int m, int[] nums2, int n){
		 int temp= m+n-1;
		/*nums1=Arrays.copyOf(nums1, temp);
		 --temp;*/
		 --m;
		 --n;
		 while(m>=0&&n>=0){
			nums1[temp--]=nums1[m]>nums2[n]?nums1[m--]:nums2[n--];
		 }
		 while(n>=0){
			 nums1[temp--]=nums2[n--];
		 }
		 for (int i : nums1) {
			System.out.print(i+" ");
		}

翻转数组

 public void rotate(int[] nums, int k){
		 int length=nums.length;
		 k=k%length;//当K大于数组长度时,相当翻转成原来的数组,取余是为了得出翻转成原来的数组后又翻转的次数
		 if(length==1){
			 return;
		 }
		 if(k==0&&k==length){
			 return;
		 }
		 Filp(nums,0,length-k-1);//翻转k位之前的数字
		 Filp(nums,length-k,length-1);//翻转k位之后的数字
		 Filp(nums,0,length-1);//翻转整个数组
	     for (int i : nums) {
					System.out.print(" "+i);
				}
		        System.out.println(" ");
	 }
	private void Filp(int[] nums, int i, int j) {
		// TODO 自动生成的方法存根
		int temp;
		while(i<j&&i>=0){
			temp=nums[i];
			nums[i]=nums[j];
			nums[j]=temp;
			i++;
			j--;
		}

第二种方法,很简单但是在面对超大数组时会超时,因为移动数组很费时间

   public void rotate(int[] nums, int k) {
	        while(k>0){
	        	int temp=nums[nums.length-1];
	        	for(int i=nums.length-1;i>0;i--){
	        		nums[i]=nums[i-1];
	        		
	        	}
	        	nums[0]=temp;
	        	k--;
	        }
	        for (int i : nums) {
				System.out.print(" "+i);
			}
	        System.out.println(" ");
	    }

 只出现一次的数字

用两层循环记录每个数字出现的次数,然后存在map里面,最后返回键值为一的value即可

	HashMap<Integer,Integer>map=new HashMap<>();
		int count=1;
		for(int i=0;i<nums.length;i++){
			count=1;
			for(int j=0;j<nums.length;j++){
				if(i==j)
					continue;
				if(nums[i]==nums[j]){
					count++;
				}				
			}
			map.put(count,nums[i]);
		}	
		return map.get(1);

上面的方法可以通过但是太耗时间,花了700多ms 在网上了解到java的异或运算符,利用异或运算符的特性可以很快的完成这道题

 int result=0;
		 for(int i=0;i<nums.length;i++){
			 result^=nums[i];
		 }
		 return result;

相同数字异或为0,不同数字数字异或为1, 

两个数组的交集II

 public int[] intersect(int[] nums1, int[] nums2) {
		 ArrayList<Integer> list = new ArrayList<>();

		    Map<Integer, Integer> map = new HashMap<Integer, Integer>();

		    for (int i = 0; i < nums1.length; i++) {
		        Integer value = map.get(nums1[i]);
		        map.put(nums1[i], (value == null ? 0 : value) + 1);
		    }

		    for (int i = 0; i < nums2.length; i++) {
		        if (map.containsKey(nums2[i]) && map.get(nums2[i]) != 0) {
		            list.add(nums2[i]);
		            map.put(nums2[i], map.get(nums2[i]) - 1);
		        }
		    }

		    int[] nums3 = new int[list.size()];
		    int i = 0;
		    for (Integer e : list)
		        nums3[i++] = e;
		    return nums3;
	        
	    }

移动零

采用两个指针,都指向数组的最后一位,一个指针向前查找零的位置,找到零后,把数组向前移动,然后把第二个指针的位置改为零。

public void moveZeroes(int[] nums){
		int one=nums.length-1;
		int two=nums.length-1;
		
		while(two>=0){
			if(nums[two]==0){
				int count=one-two;
				for(int i=0;i<count;i++){
					nums[two+i]=nums[two+i+1];
				}
				nums[one]=0;
				one--;
			}
			two--;
		}
		for (int i : nums) {
			System.out.print(" "+i);
		}
	}

有效的数独

只需要判断行有没有重复,列有没有重复,3×3方块有没有重复即

public boolean isValidSudoku(String[][] board) {
		HashSet<String> rowSet=new HashSet<>();
		HashSet<String> colSet=new HashSet<>();
		
		
		for(int i=0;i<9;i++){
			rowSet.clear();
			colSet.clear();
			for(int j=0;j<9;j++){
				if(i%3==0&&j%3==0){//检查3×3有没有重复数字
					if(!CheckBlock(board, i, j))
						return false;
				}
				if(board[i][j]!="."){//检查行有没有重复数字
					if(rowSet.contains(board[i][j]))
						return false;
					rowSet.add(board[i][j]);
				}
				if(board[j][i]!="."){//检查列有没有重复数字
					if(colSet.contains(board[j][i]))
						return false;
					colSet.add(board[j][i]);
				}
			}
		}
		
        return true;
    }
	public boolean CheckBlock(String[][]board,int row,int col){
		HashSet<String> blockSet=new HashSet<>();
		for(int i=row;i<row+3;i++){
			for(int j=col;j<col+3;j++){
				if(board[i][j]!="."){
					if(blockSet.contains(board[i][j]))
						return false;
					blockSet.add(board[i][j]);
					
				}
			}
		}
		return true;
		
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Lpepsi

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

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

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

打赏作者

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

抵扣说明:

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

余额充值