【算法】算法进阶

文章目录

1.整数

1.1判断一个数是不是回文数
public boolean isPalindrome(int x) {
    if (x<0 || (x!=0 && x%10==0)) return false;
    int rev = 0;
    while (x>rev){
    	rev = rev*10 + x%10;
    	x = x/10;
    }
    return (x==rev || x==rev/10);
}
1.2LeetCode231. Power of Two(判断一个数是不是2的n次幂)
class Solution {
    public boolean isPowerOfTwo(int n) {
        return (n > 0) && ((n & (n-1)) == 0);
    }
}
1.3整数中1出现的次数,即从1到n整数中1出现的次数(剑指Offer)

求出113的整数中1出现的次数,并算出1001300的整数中1出现的次数?为此他特别数了一下1~13中包含1的数字有1、10、11、12、13因此共出现6次,但是对于后面问题他就没辙了。ACMer希望你们帮帮他,并把问题更加普遍化,可以很快的求出任意非负整数区间中1出现的次数。

public class Solution {
    public int NumberOf1Between1AndN_Solution(int n) {
       int count=0;
       StringBuilder link=new StringBuilder();
       for(int i=0;i<n+1;i++)
           link.append(i);
       String test=link.toString();
       for(int j=0;j<test.length();j++)
           {
           if(test.charAt(j)=='1')    //这里是最需要注意的地方
               count++;
            }
       return count;
       }
}

2.数组

2.1LeetCode27 Remove Element

Given an array and a value, remove all instances of that value in place and return the new length.
Do not allocate extra space for another array, you must do this in place with constant memory.
The order of elements can be changed. It doesn’t matter what you leave beyond the new length.

Example:
Given input array nums = [3,2,2,3], val = 3
Your function should return length = 2, with the first two elements of nums being 2.
解答:


public class Solution {
    public int removeElement(int[] nums, int val) {
        int m=0;
        for(int j=0;j<nums.length;j++){
            if(nums[j]!=val){
                nums[m]=nums[j];
                m++;
       }}
        return m;
    }
}
2.2连续子数组的最大和(剑指Offer)

一个整数数组中的元素有正有负,在该数组中找出一个连续子数组,要求该连续子数组中各元素的和最大,这个连续子数组便被称作最大连续子数组。

public class Solution {  
    public int FindGreatestSumOfSubArray(int[] array) {  
        if(array.length==0)  
            return 0;  
        int temp=array[0];                        
        int sum=array[0];                       //这个sum一定要是array[0],为了防止数组全是负数  
        for(int i=1;i<array.length;i++)         //注意这个i的起始值是1  
            {  
            if(temp>0)  temp=temp+array[i];     //如果前一段和>0,保留temp  
            else  
            temp=array[i];                      //如果前一段和<0,舍弃temp  
            if(temp>sum)  
            sum=temp;  
            }  
        return sum;  
    }  
2.3数组中只出现一次的数字

一个整型数组里除了两个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。

//num1,num2分别为长度为1的数组。传出参数
//将num1[0],num2[0]设置为返回结果
public class Solution {
    public void FindNumsAppearOnce(int [] array,int num1[] , int num2[]) {
        int match=0;
        int flag=1;
        if(array.length<2)
            return;
        for(int i=0;i<array.length;i++){
            match^=array[i];
        } 
        //如果有两个数字不相同,那么肯定macth有一位是1,然后通过while找到那个1 进行分组!
        while((match&flag)==0) flag<<=1;    //找到那个1
        for(int j=0;j<array.length;j++)
        {
            if((flag&array[j])==0) num1[0]^=array[j];
                else 
                   num2[0]^=array[j];      
        }       
    }
}
2.4LeetCode217 Contains Duplicate(判断数组是否包含重复值)

Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.


public class Solution {  
    public boolean containsDuplicate(int[] nums) {  
        Set<Integer> a=new HashSet<Integer>();  
       for(int i:nums){  
           if(!a.add(i))  
        return true;  
       }  
        return false;  
    }  
} 
2.5第一个只出现一次的字符

在一个字符串(1<=字符串长度<=10000,全部由字母组成)中找到第一个只出现一次的字符,并返回它的位置

import java.util.*;
 
public class Solution {
        public int FirstNotRepeatingChar(String str) {
                Map<Character, Integer> map = new HashMap<Character, Integer>();
        for(int i=0;i<str.length();i++){
            if(map.containsKey(str.charAt(i))){
                int time = map.get(str.charAt(i));
                map.put(str.charAt(i), ++time);
            }
            else {
                map.put(str.charAt(i), 1);
            }
        }
        for(int i=0;i<str.length();i++){
            char c = str.charAt(i);
            if (map.get(c) == 1) {
                return i;
            }
        }
        return -1;
       }
}
2.6Remove Duplicates from Sorted Array

Given a sorted array, remove the duplicates in-place such that each element appear only once and return the new length.

Do not allocate extra space for another array, you must do this by modifying the input array in-place with O(1) extra memory.


Given nums = [1,1,2],
 
Your function should return length = 2, with the first two elements of nums being 1 and 2 respectively.
It doesn't matter what you leave beyond the new length.

解答:


public int removeDuplicates(int[] nums) {
    int cur = 0 ; 
    for(int n:nums)
        if(n>nums[cur])
            nums[++cur] = n;
    return cur+1;
}
2.7LeetCode238 Product of Array Except Self(数组元素除它自身之外的乘积)

Given an array nums of n integers where n > 1, return an array out such that output[i] is equal to the product of all the elements of nums except nums[i]

Input:  [1,2,3,4]
Output: [24,12,8,6]

Note: Please solve it without division and in O(n).
解题思路:

先遍历数组左边的相乘,然后再乘以右边的。


class Solution {
    public int[] productExceptSelf(int[] nums) {
        int n = nums.length;
        int [] result = new int[n];
        result[0] = 1;
        for (int i = 1; i < n; i++){
            result[i] = result[i -1] * nums[i - 1];   
        }
        int right = 1;
        for (int i = n - 1; i >= 0; i--){   //注意边界
            result[i] = result[i] * right;
            right = right * nums[i];      
        }
        return result;
    }
}

3.链表

3.1倒数第k个节点(剑指Offer)
/* 
public class ListNode { 
    int val; 
    ListNode next = null; 
 
    ListNode(int val) { 
        this.val = val; 
    } 
}*/  
public class Solution {  
    public ListNode FindKthToTail(ListNode head,int k) {     
      if(head==null||k==0)  
          return null;                              //防止链表是空   或者倒数第0个结点  
      ListNode p1=head;                             //倒数越界  
      ListNode p2=head;                               
      int i=1;  
      while(i<k){                                        //从1个节点去第k个节点,就是往前走k-1步  
          if(p1.next==null)                              //主要是防止K大于了链表的长度,p1.next是空,说明将要越界了。  
              return null;  
          p1=p1.next;  
          i++;  
      }  
      while(p1.next!=null){  
          p1=p1.next;  
          p2=p2.next;  
      }  
      return p2;  
      }  
}  

这个题的思路是设立两个结点,让第一个先走到k节点,然后两个节点同时往后走,当第一个结点走到最后一个结点时,第二个正好走到倒数第K个节点。

3.2LeetCode83 Remove Duplicates from Sorted List(删除排序链表中的重复元素)

Given a sorted linked list, delete all duplicates such that each element appear only once.

For example,
Given 1->1->2, return 1->2.

Given 1->1->2->3->3, return 1->2->3.

注意:这里是排序好的!
解答:

/** 
 * Definition for singly-linked list. 
 * public class ListNode { 
 *     int val; 
 *     ListNode next; 
 *     ListNode(int x) { val = x; } 
 * } 
 */  
  
class Solution {  
    public ListNode deleteDuplicates(ListNode head) {  
        if(head==null||head.next==null)  
         return head;                     //     如果链表为空或只有一个节点,返回null或这个节点就可以  
        ListNode temp=head;                        
        while(temp.next!=null){           //     如果当前结点的下一个节点不为空,比较当前结点和下一个结点  
        if(temp.next.val==temp.val)  
            temp.next=temp.next.next;     //     如果当前结点和下一个结点相同,直接将下一个节点改为下下结点  
        else  
            temp=temp.next;               //     如果不同,继续往后  
        }  
        return head;  
    }  
}  
3.3LeetCode82 Remove Duplicates from Sorted List II(删除排序链表的重复元素2)

Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numbers from the original list.

For example,
Given 1->2->3->3->4->4->5, return 1->2->5.
Given 1->1->1->2->3, return 2->3

解答:

class Solution {  
    public ListNode deleteDuplicates(ListNode head) {  
            if (head == null) return null;  
      
    if (head.next != null && head.val == head.next.val) {              //如果当前结点和他下一结点相等         
        while (head.next != null && head.val == head.next.val) {         
            head = head.next;                                          //head一直往后  
        }  
        return deleteDuplicates(head.next);                            //把这一段的舍去,然后判断剩下的  
    } else {  
        head.next = deleteDuplicates(head.next);                       //如果不相等保留,从下一个结点继续判断  
    }  
    return head;                                                         
    }  
}  
3.4约瑟夫环(程序员面试金典)

约瑟夫问题是一个非常著名的趣题,即由n个人坐成一圈,按顺时针由1开始给他们编号。然后由第一个人开始报数,数到m的人出局。现在需要求的是最后一个出局的人的编号。

给定两个int n和m,代表游戏的人数。请返回最后一个出局的人的编号。保证n和m小于等于1000。

import java.util.*;  
public class Joseph {  
    public int getResult(int n, int m) {  
      
        LinkedList<Integer> test=new LinkedList<Integer>();   //注意链表初始化,别忘了()  
        for (int i=1;i<=n;i++)  
        {test.add(i);}  
        int start=0;  
        while(test.size()>1){                                 //注意链表长度取法  
            int need=(start+m-1)%test.size();  
            test.remove(need);  
            start=need%test.size();  
            }  
            return test.get(0);  
    }  
 }      
3.5LeetCode203. Remove Linked List Elements(移除链表元素)
/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode removeElements(ListNode head, int val) {
        while(head != null && head.val == val) {
            head = head.next;
        }
        if(head == null)
            return head;
        ListNode temp = head;
        while(temp.next != null){
            if(temp.next.val == val){
            temp.next = temp.next.next;}
            else{
            temp = temp.next;}
        }
        return head;
    }
}

4.二叉树

4.1LeetCode104 Maximum Depth of Binary Tree(求二叉树的最大深度)
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int maxDepth(TreeNode root) {
       if(root==null) return 0;
       int  left=maxDepth(root.left);
       int  right=maxDepth(root.right);
       return 1+Math.max(left,right);
    }
}
4.2LeetCode111 Minimum Depth of Binary Tree(求二叉树的最小深度)
**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int minDepth(TreeNode root) {
        if(root==null) return 0;
        int left=minDepth(root.left);
        int right=minDepth(root.right);
        return (left==0||right==0)?left+right+1:Math.min(left,right)+1;    
}
}

注意防止斜树

4.3等价二叉树(剑指Offer)
/** 
 * Definition of TreeNode: 
 * public class TreeNode { 
 *     public int val; 
 *     public TreeNode left, right; 
 *     public TreeNode(int val) { 
 *         this.val = val; 
 *         this.left = this.right = null; 
 *     } 
 * } 
 */  
  
  
public class Solution {  
    /* 
     * @param a: the root of binary tree a. 
     * @param b: the root of binary tree b. 
     * @return: true if they are identical, or false. 
     */  
    public boolean isIdentical(TreeNode a, TreeNode b) {  
        // write your code here  
        if(a==null&&b==null)  return true;  
        if(a==null||b==null)  return false;  
        if(a.val==b.val) return isIdentical(a.left,b.left)&&isIdentical(a.right,b.right);  
        else  
        return false;  
          
          
    }  
}  
4.4LeetCode404 Sum of Left Leaves(左叶子节点和)
    3
   / \
  9  20
    /  \
   15   7
 
There are two left leaves in the binary tree, with values 9 and 15 respectively. Return 24.
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
public class Solution {
    public int sumOfLeftLeaves(TreeNode root) {
        int sum=0;
        if(root==null)                  
            return 0;
        if(root.left!=null)
        {
            if((root.left.left==null)&&(root.left.right==null)){
                sum=sum+root.left.val;
            }else
            sum=sum+sumOfLeftLeaves(root.left);
        }
        sum=sum+sumOfLeftLeaves(root.right);
        return sum;
    }
  }
4.5二叉树中和为某一值的路径(剑指Offer)
import java.util.ArrayList;  
/** 
public class TreeNode { 
    int val = 0; 
    TreeNode left = null; 
    TreeNode right = null; 
 
    public TreeNode(int val) { 
        this.val = val; 
        } 
*/  
public class Solution {  
    private ArrayList<Integer> child=new ArrayList<Integer>();  
    private ArrayList<ArrayList<Integer>> father=new ArrayList<ArrayList<Integer>>();  
    public ArrayList<ArrayList<Integer>> FindPath(TreeNode root,int target) {  
        if(root==null)  
            return father;  
        child.add(root.val);  
        target-=root.val;                                  //通过一个节点就减去这个节点的值  
        if(target==0&&root.left==null&&root.right==null)   //关键1  如果是叶子结点且target已经减到0了  
            father.add(new ArrayList<Integer>(child));     //关键2  注意的是这种写法  
        FindPath(root.left,target);                          
        FindPath(root.right,target);                         
        child.remove(child.size()-1);   //关键3  
        return father;  
    }  
}  
4.6树的子结构—判断B是不是A的子结构(剑指Offer)

输入两棵二叉树A,B,判断B是不是A的子结构。(ps:我们约定空树不是任意一个树的子结构)

/** 
public class TreeNode { 
    int val = 0; 
    TreeNode left = null; 
    TreeNode right = null; 
 
    public TreeNode(int val) { 
        this.val = val; 
 
    } 
 
} 
*/  
public class Solution {  
    public boolean HasSubtree(TreeNode root1,TreeNode root2) {  
       boolean temp=false;     
       if(root1!=null && root2!=null){  
           if(root1.val==root2.val)                         //当遇到结点相等时,开始判断  
              temp=doS(root1,root2);  
           if(!temp){                                      
              temp=HasSubtree(root1.left,root2);            //结点不相等,再判断A树左节点  
           }  
           if(!temp){  
              temp=HasSubtree(root1.right,root2);           //判断A树右节点  
           }  
       }  
      return temp;  
    }  
      
    public boolean doS(TreeNode root1,TreeNode root2)  
    {  
        if(root2==null)                                     //如果B树走完了,说明A树完全包含了B树  
            return true;    
        if(root1==null)                                     //如果A树走完了,B树未走完,说明A树不完全包含B树,记住和上面不能颠倒  
            return false;            
        if(root1.val!=root2.val)                            //判断结点是否相等,不相等返回false  
            return false;  
        return doS(root1.left,root2.left)&&doS(root1.right,root2.right);  //继续判断A树B树左节点,A树B树右节点  
    }  
 }  
4.7LeetCode110 Balanced Binary Tree(判断是不是平衡二叉树)

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

/** 
 * Definition for a binary tree node. 
 * public class TreeNode { 
 *     int val; 
 *     TreeNode left; 
 *     TreeNode right; 
 *     TreeNode(int x) { val = x; } 
 * } 
 */  
class Solution {  
    boolean result=true;  
    public boolean isBalanced(TreeNode root) {  
        TestIsBalanced(root);  
        return result;  
    }  
    public int TestIsBalanced(TreeNode root){  
        if(root==null)  
            return 0;  
        int l=TestIsBalanced(root.left);  
        int r=TestIsBalanced(root.right);  
        if(Math.abs(l-r)>1)              //注意绝对值用法  
             result=false;               //注意这里没有return  
        return 1+Math.max(l,r);  
        }  
}  
4.8求二叉树的最大宽度
public static int getMaxWidth(TreeNode root) {  
        if (root == null)  
            return 0;  
  
        Queue<TreeNode> queue = new ArrayDeque<TreeNode>();  
        int maxWitdth = 1; // 最大宽度  
        queue.add(root); // 入队  
  
        while (true) {  
            int len = queue.size(); // 当前层的节点个数  
            if (len == 0)  
                break;  
            while (len > 0) {// 如果当前层,还有节点  
                TreeNode t = queue.poll();  
                len--;  
                if (t.left != null)  
                    queue.add(t.left); // 下一层节点入队  
                if (t.right != null)  
                    queue.add(t.right);// 下一层节点入队  
            }  
            maxWitdth = Math.max(maxWitdth, queue.size());  
        }  
        return maxWitdth;  
}  
4.9二叉树的所有路径

Given a binary tree, return all root-to-leaf paths.For example, given the following binary tree:

   1
 /   \
2     3
 \
  5

["1->2->5", "1->3"]
/**
 * Definition for a binary tree node.
 * public class TreeNode {
 *     int val;
 *     TreeNode left;
 *     TreeNode right;
 *     TreeNode(int x) { val = x; }
 * }
 */
class Solution {
    public List<String> binaryTreePaths(TreeNode root) {
       List<String> test=new ArrayList<String>();   //数组是对象,引用传递
       if(root!=null) searchBT(root,"",test);
       return test;
    }
    public void searchBT(TreeNode root,String path,List<String> test)
    {
        if((root.left==null)&&(root.right==null)) test.add(path+root.val);//注意r:string+int就是string了 
        if(root.left!=null)  searchBT(root.left,path+root.val+"->",test);
        if(root.right!=null) searchBT(root.right,path+root.val+"->",test);    
    }
}

5.综合算法

5.1矩形覆盖(剑指Offer)

我们可以用21的小矩形横着或者竖着去覆盖更大的矩形。请问用n个21的小矩形无重叠地覆盖一个2*n的大矩形,总共有多少种方法?

public class Solution {
    public int RectCover(int target) {
       if(target==1||target==0)
           return target;
       else if(target==2)
            return 2;
       else 
       return RectCover(target-1)+RectCover(target-2);
    }
}
5.2Leetcode121 Best Time to Buy and Sell Stock(买卖股票的最佳时机1)

Say you have an array for which the ith element is the price of a given stock on day i.

If you were only permitted to complete at most one transaction (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.
例子:

Input: [7, 1, 5, 3, 6, 4]
Output: 5
max. difference = 6-1 = 5 (not 7-1 = 6, as selling price needs to be larger than buying price)
Input: [7, 6, 4, 3, 1]
Output: 0
In this case, no transaction is done, i.e. max profit = 0.

解答:

class Solution {
    public int maxProfit(int[] prices) {
        if(prices.length==0)
            return 0;
        int min=prices[0];              //先把第一个值设为最小值
        int profit=0;                     
        for(int i=0;i<prices.length;i++)
        {
            if(prices[i]<min)          //如果当前值小于最小值(买入点),把最小值改为当前值
                min=prices[i];
            if(prices[i]-min>profit)   //如果利润大于以前的利润,则把最大利润换成当前情况的
                profit=prices[i]-min;
        }
        return profit;
      }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值