算法日记

选择排序:首先找到最小的那个元素将其与数组的第一个元素进行交换,再次从剩下的元素中找到最小的元素,将其与第二个元素交换,以此类推。选择排序大约需要N~2/2次比较和N次交换。

public class Selections{

public static void sort(int a[]){
  int N=a.length;
  for(i=0;i<N;i++){
    int min=i;
    for(j=i+1;i<N;j++){
     if (a[min]>a[j]){
        min=j;
        exchange(a,i,min);
       }
    }
  }

}
public static void exchange(a,int i,int j){
int temp=a[i];
a[i]=a[j];
a[j]=temp;

   }
}

第一个元素先确定为最小,然后和剩下其他的元素比较,那个最小和第一个元素交换,余下类似;

插入排序:类似于抓牌排序

public class Insertion{
  public static void sort(int a[]){
     int N=a.length;
     for(i=1;i<N;i++){
        for(j=i-1;j>=0&&(a[j]>a[i]);j++){
           exchange(a,i,j);        
        }
    }
}
  public static exchange(a,int i,int j){
       int temp=a[j];
       a[i]=temp;
       a[j]=a[i];

}
}

插入排序对几乎有序的排序更有效,而选择排序都是交换和排序。

希尔排序:

public class shell{
  public static void sort(int a[]){
    int N=a.length;
    int h=1;
    while(h<N/3){
    h=3*h+1;
  }
    while(h>=1){
    for(int i=h;i<N;i++){
       for(int j=i;j>=h&&a[j]>a[j-h];j-=h){
           exchange(a,j-h,j);  
       }
       h=h/3;
    }
  }
}
  public static exchange(a,i,j){
int temp=a[i];
a[j]=a[i];
a[j]=temp;
   }
}
public class Solution{
   public int lengthOfLongestSubstring(String s) {
      int N=s.length();
int res=0;
      for(int start=0;start<N;start++){
         for(int end=start+1;end<N;end++){

               if(istrue(s,start,end)){
                     Math.max(res,end-start)
       }
}
return res;

}

public boolean istrue(String s,int i,int j){
         Set<string> set=new HashSet<string>();
         for(;i<j;i++){
         if(set.contains(s.indexOf(i))){
               boolean req=true;
               set.remove(i++);
          }else{
               req=false;
               set.add(s.indexOf(i++)  
        
}
}
return req;

} 




}

}
public class Solution{
   public int lengthOfLongestSubstring(String s) {
   if s.length()==0 ;return 0;
      int N=s.length();
      int start=0;
      int end=0;
      int req=0;
      Set<String> set=new HashSet<String>();
      while(start<N&&end<N){
      if(set.contains(s.chatAt(end)){
       set.remove(s.chatAt(start++))           
}else{
       set.add(s.chatAt(end++))
       req=Math.max(res,end-start);
 
  }
}    
return req;
    }
}
public class Solution{
   public int lengthOfLongestSubstring(String s) {
      int maxLength=0;
      if s.length()==0 ;return 0;
      List<Character> list=new ArrayList<Character>();
      list.add(s.charAt(0));
      for(int start=1;i<s.length;start++){
      if(list.contains(s.charAt(start))){
       int index=list.indexOf(s.chatAt(start));
       list=list.subList(index+1,list.size());
       list.add(s.chatAt(start));
       maxLength=Math.max(maxlenth,list.size()); 
}else{
       list.add(s.chatAt(start));
       maxLength=Math.max(maxlenth,list.size());
}
}    
return maxlength;
    }
}

最短以及最长字符串子串选用滑动窗口法,该算法展示了如何将嵌套for循环在少数问题中转换为单个for循环,从而减少了时间的复杂性。

7

class Solution {
    public int reverse(int x) {
       int num=0;
       int n=0;
       int [] a=new int[100];
       int flag=0
       if (x>0) flag=1; 
       x=Math.abs(x);
       while(x!=0){
         a[n++]=x%10;
         x=x/10;
       }
       int ans,t=0;
       for(int i=0,i<n;i++){
           //t=Math.pow(10,n-1-i);
           //num+=a[i]*t;
           //if(num/t!=10) return 0;
            t=ans;
            ans=t*10+a[i];
            if(t!=ans/10) return 0;
        }
       if(flag==0) num=-num;
       return num;
    }
}

LeetCode 5 最长回文 动态规划:

class Solution {
    public String longestPalindrome(String s) {
       boolean[][] flag = new boolean[s.length()][s.length()];
        int begin = 0;
        int end = 0;
        int maxlen = 0;
 
        for (int i = s.length(); i >= 0; i--) {
            for (int j = i; j < s.length(); j++) {
                if (s.charAt(i)==s.charAt(j) && (j-i <= 2 || flag[i+1][j-1])){
                    flag[i][j] = true;
                    if (maxlen < j-i+1){
                        maxlen = j-i+1;
                        begin = i;
                        end = j;
                    }
                }
            }
        }
 
        if(s.length()>0){
            return s.substring(begin,end+1);
        }else{

        return s;
        }
        
    }
}

中心扩展法:

class Solution {
    public String longestPalindrome(String s) {
        int begin = 0;
        int end = 0;
        int maxlen = 0;
        //类似于aba这种结构,指的是子串,并不是字符串
       
        for (int i = 0; i< s.length(); i++) {
                int j=i-1;
                int k=i+1;
                while(j>=0&&k<s.length()&&s.charAt(j)==s.charAt(k)){
                    
                     if (maxlen < k-j+1){
                        maxlen = k-j+1;
                        begin = k;
                        end = j;
                    
                }
            j--;
            k++;
            }
        }

         for (int i = 0; i<s.length(); i++) {
                int j=i;
                int k=i+1;
                while(j>=0&&k<s.length()&&s.charAt(j)==s.charAt(k)){
                    
                     if (maxlen < k-j+1){
                        maxlen = k-j+1;
                        begin = k;
                        end = j;
                    }
                
            j--;
            k++;
            
            }
        }

        if(maxlen>0){
            return s.substring(begin,end+1);
        }else if(s.length()>0){

        return s.substring(s.length()-1,s.length());
        }else{
        return s;
        }
    }
}

class Solution {
    String longest = "";
    public String longestPalindrome(String s) {
         
        for(int i = 0; i < s.length(); i++){
            helper(s, i, 0);
            helper(s, i, 1);
        }
        return longest;
    }
    private void helper(String s, int idx, int offset){
        int left = idx;
        int right = idx + offset;
        while(left>=0 && right<s.length() && s.charAt(left)==s.charAt(right)){
            left--;
            right++;
        }
        String currLongest = s.substring(left + 1, right);
        if(currLongest.length() > longest.length()){
            longest = currLongest;
        }
    }
}

leetcode 4 

here are two sorted arrays A and B of size m and n respectively. Find the median of the two sorted arrays. The overall run time complexity should be O(log (m+n)).

两个排好序的的数组找中位数,时间复杂度要求 O(log (m+n)).

如果把两个数组合并,排序再找中位数,显然时间复杂度是O(nlogn).

问题转换为求两个数组中第K个小的元素.参考http://blog.csdn.net/yutianzuijin/article/details/11499917/

首先假设数组A和B的元素个数都大于k/2,我们比较A[k/2-1]和B[k/2-1]两个元素,这两个元素分别表示A的第k/2小的元素和B的第k/2小的元素。这两个元素比较共有三种情况:>、<和=。如果A[k/2-1]<B[k/2-1],这表示A[0]到A[k/2-1]的元素都在A和B合并之后的前k小的元素中。换句话说,A[k/2-1]不可能大于两数组合并之后的第k小值,所以我们可以将其抛弃。

当A[k/2-1]>B[k/2-1]时存在类似的结论。

当A[k/2-1]=B[k/2-1]时,我们已经找到了第k小的数,也即这个相等的元素.

  • 如果A或者B为空,则直接返回B[k-1]或者A[k-1];
  • 如果k为1,我们只需要返回A[0]和B[0]中的较小值;
  • 如果A[k/2-1]=B[k/2-1],返回其中一个;
class Solution {
   public double findMedianSortedArrays(int[] nums1, int[] nums2) {
        int a=nums1.length;
        int b=nums2.length;
        int totalnums=a+b;
        if(totalnums%2==1){
            return findKth(nums1,0,a,nums2,0,b,totalnums/2+1);
        }else{
   return(findKth(nums1,0,a,nums2,0,b,totalnums/2)+findKth(nums1,0,a,nums2,0,b,totalnums/2))/2;
        
      }
   
    }
       public static double findKth(int nums1[],int abegin,int a,int nums2[],int bbegin,int b,int k){
       if(a>b) return findKth(nums2,bbegin,b,nums1,abegin, a,k);
       if(k==1) return Math.min(nums1[abegin],nums2[bbegin]);
       if(a==0) return nums2[abegin+k-1];
       int ma=Math.min(k/2,a);int mb=k-ma;
      if(nums1[abegin+ma-1]<nums2[bbegin+mb-1])
            return findKth(nums1,abegin+ma,a-ma,nums2,bbegin,b,k-ma);
      else if(nums1[abegin+ma-1]>nums2[bbegin+mb-1])
            return findKth(nums1,abegin,a,nums2,bbegin+mb,b-mb,k-mb);
      else return nums2[bbegin+mb+1];
     
    }
}

LeetCode 13 数字变成罗马数

class Solution {
       public int romanToInt(String s) {

         if(s==null||s.length()<1) return -1;
         char []ch=s.toCharArray(); 
         HashSet<Character,Integer> hash=new HashSet<Character,Integer>();
        hash.put('M',1000);
        hash.put('D',500);
        hash.put('C',100);
        hash.put('L',50);
        hash.put('X',10);
        hash.put('V',5);
        hash.put('I',1);
        int res=0;//总和
        int temp=0;//上一次的值
        int value=0;//这次的值
        for(int i=ch.length-1;i>=0;i--){
                value=hash.get(ch[i]);
                if(temp<=value){
                   res+=value;
                   temp=value; 
                }esle{
                   res-=value;
                   temp=value; 
            }
            return res;
        }
}

LeetCode 2 两个数相加

估计是学会使用链表

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {
      ListNode headNode = new ListNode(0);  
        ListNode currentNode = headNode;  
        
        int carray = 0;  
        while(l1 != null || l2 != null){  
            if(l1!=null){
                carray +=l1.val;
                l1 = l1.next;
            }
            if(l2!=null){
                carray +=l2.val;
                l2 = l2.next;
            }
           currentNode.next = new ListNode(carray%10);
           currentNode = currentNode.next;
           carray/=10;
           
        }
        
        if(carray==1){
            currentNode.next = new ListNode(1);
            currentNode = currentNode.next;
        }
       return headNode.next;
  }
}

13水桶问题:装最多的水

class Solution {
    public int maxArea(int[] height) {

        int l=0;
        int r=height.length;
        int contain=0;
        while(l<r){
            int high=Math.min(height[l],height[r]);
            contain=Math.max(contain,(r-l)*high);
            while(height[l]<=high&&l<r) l++;
            while(height[r]<=high&&l<r) r--;
        }
    return contain;
    }
}


class Solution {
    public int maxArea(int[] height) {

        int N=height.length;
        int contain=0;
        int temp=0;
        for(int i=0;i<N;i++){
            for(int j=i+1;j<N;j++){
                temp=(j-i)*Math.min(height[i],height[j]);
                contain=Math.max(contain,temp);
            }

        }
       return contain;
      }
    }
}

LeetCode12 Integer to Roman

class Solution {
    public String intToRoman(int num) {
    String [] m={"","M","MM","MMM"};
    String [] c={"","C","CC","CCC","CD","D","DC","DCC","DCCC","CM"};
    String [] x={"","X","XX","XXX","XL","L","LX","LXX","LXXX","XC"};
    String [] i={"","I","II","III","IV","V","VI","VII","VIII","IX"};
       return m[num/1000]+c[num%1000/100]+x[num%100/10]+i[num%10];
    }
}
I             1
V             5
X             10
L             50
C             100
D             500
M             1000
class Solution {
    public String intToRoman(int num) {
    String [] str={"M","CM","D","CD","C","XC","L","XL","X","IX","V","IV","I"};
    int [] nums={1000,900,500,400,100,90,50,40,10,9,5,4,1};
    StringBuilder strbuilder=new StringBuilder();
    
    for(int i=0;i<nums.length;i++){
        int  count=num/nums[i];
        while(count!=0){
            strbuilder.append(str[i]);
            count--;
            }
        num=num%nums[i];
        }    
    return strbuilder.toString();

    }
}

leetcode 3sum

Example:

Given array nums = [-1, 0, 1, 2, -1, -4],

A solution set is:
[
  [-1, 0, 1],
  [-1, -1, 2]
]
class Solution {
    public List<List<Integer>> threeSum(int[] nums) {
         List<List<Integer>> res=new ArrayList<List<Integer>>();
        if(nums==null||nums.length<=2) return res;
        Arrays.sort(nums);
        for(int i=0;i<nums.length;i++){
            if(nums[i]>0) break;
            if(i>0&&nums[i]==nums[i-1]) {continue;}
            int left=i+1; int right=nums.length-1;
            int sum=-nums[i];
            while(left<right){
                if(nums[left]+nums[right]==sum){
                   ArrayList<Integer> triplet = new ArrayList<>();
                   triplet.add(nums[left]);
                   triplet.add(nums[right]);
                   triplet.add(nums[i]);
                    res.add(triplet);
                    while(left<right&&nums[left++]==nums[left]){}
                    while(left<right&&nums[right--]==nums[right]){}
                    }else if(nums[left]+nums[right]<sum){
                    while(left<right&&nums[left++]==nums[left]){}
                    }else{
                    while(left<right&&nums[right--]==nums[right]){} 
                 }
            }
        
        }
  return res;  

    }
}

先对列表进行排序,然后从头到尾遍历。这样每次都固定住一个值,而不是用双指针来解决三值问题,好像是可行的。

在固定一个值之后,剩下的有序列表中,用双指针法寻找两个值的和是否是固定值的负数。这样指针移动的标准也就出来了。如下图:


当两值之和大于固定值的负数时,右边的指针左移
当两值之和小于固定值的负数时,左边指针右移
当两值之和恰好为固定值负数,保存结果。此时有个很有必要的操作:判断 start+1的值,end-1的值,是否与上一个一样,相同的话,则跳过处理
leetcode 10 正则表达式的匹配

class Solution {
    public boolean isMatch(String s, String p) {
         boolean [][] rex=new boolean[s.length()+1][p.length()+1];
        for(int i=0;i<s.length()+1;i++){
            for(int j=0;j<p.length()+1;j++){
                rex[i][j]=false;
            }
        }
        rex[0][0]=true;
        for(int i=0;i<=s.length();i++){
            for(int j=1;j<=p.length();j++){
                if(i > 0 && (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.')){
                    rex[i][j]=rex[i-1][j-1];
                }
                if(p.charAt(j-1)=='*'){
                    if(i==0||(s.charAt(i-1)!=p.charAt(j-2)&&p.charAt(j-2)!='.')){ 
                       rex[i][j]=rex[i][j-2];
                    }else{
                        rex[i][j]=rex[i-1][j]||rex[i][j-1]||rex[i][j-2];
                     }
              }
           }
       }
        return rex[s.length()][p.length()]; 
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值