做几个leetcode数组题

1.

Remove Duplicates from Sorted Array

 Total Accepted: 29864 Total Submissions: 91835My Submissions

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

Do not allocate extra space for another array, you must do this in place with constant memory.

For example,
Given input array A = [1,1,2],

Your function should return length = 2, and A is now [1,2].


解答1:

#include<iostream>

using namespace std;

int removeDuplicates(int A[], int n)

{

 for ( int i = 0; i < n ; i++)

 {

  if (A[i] == A[i + 1])

  {

   for (int j = i + 1; j < n ; j++)

    A[j] = A[j + 1];

    n--;

  }

 }

 return n;

}


int main()

{

 int A[3] = {1,1,2};

 cout<< "the result : " << removeDuplicates(A,3) << endl;

 return 0;

}

提交时,Submission Result: Time Limit Exceeded

后来各种错误,最后换向前看一个的思路

#include<iostream>

using namespace std;

int removeDuplicates(int A[], int n)

{

 int j = 1;

 if ( n == 0) j = 0;

 for ( int i = 1; i < n ; i++)

 {

  if (A[i] != A[j - 1])

  {

   A[j++] = A[i];

  }

 }

 return j;

}

int main()

{

 int A[] = {};

 cout<< "the result : " << removeDuplicates(A,0) << endl;

 return 0;

}

Submission Result: Accepted

2.是1题的延伸

Remove Duplicates from Sorted Array II

 Total Accepted: 22371 Total Submissions: 72955My Submissions

Follow up for "Remove Duplicates":
What if duplicates are allowed at most twice?

For example,
Given sorted array A = [1,1,1,2,2,3],

Your function should return length = 5, and A is now [1,1,2,2,3].

这个因为有上个的经验,一次就AC

#include<iostream>

using namespace std;

int removeDuplicates(int A[], int n)

{

 int j = 2;

 if ( n <= 2) return n;

 for ( int i = 2; i < n ; i++)

 {

  if (A[i] != A[j - 2])

  {

   A[j++] = A[i];

  }

 }

 return j;

}

int main()

{

 int A[] = {1,1,1,2,2,3};

 cout<< "the result : " << removeDuplicates(A,6) << endl;

 return 0;

}


3.

Search in Rotated Sorted Array

Suppose a sorted array is rotated at some pivot unknown to you beforehand.

(i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2).

You are given a target value to search. If found in the array return its index, otherwise return -1.

You may assume no duplicate exists in the array.

解答:

#include<iostream>

using namespace std;

int search(int A[], int n, int target)

{

    int head,tail,mid;

 head = 0 ;

 tail = n ;

 while(tail > head)   //tail没减1不用〉= 二分法,还是记住head = 0;tail = n-1; while(tail>=head)....tail = mid- 1; head = mid + 1的版本吧,即第三个方法

 {

   mid = (head + tail)/2;                                        //除以2也可以采用右移的方法,同理乘以2左移

  if (A[mid] == target) return mid;

  if(A[head] <= A[mid])

  {

   if (A[mid] >= target && A[head] <= target )

    tail = mid;

   else head = mid + 1; //不加1就会落入死循环[4],找5 ,这里把mid当head ,所以mid肯定检测过了,head取值往前加一个就好

                                    //这里有个疑问是为什么head的更新要加1而tail不用,因为除法取整只会在head,会出现mid一直等于head的无限循环,要不加1也可以见下面,至于tail想-1的话也是可以的,毕竟可以少判断一个数,见下面同时有加1和减1的版本

  }

  else

  {

   if (A[tail - 1] >= target && A[mid] <= target )         //tail如果不减1,就会越界

    head = mid + 1;

   else tail = mid;

  }

 }

 return -1;    

 

}

int main()

{

 int A[] = {4};

 cout<< "the result : " <<search(A,1,5) << endl;

 return 0;

}

2)一点改动的解法:

int head,tail,mid;

 head = 0 ;

 tail = n ;

 mid = (head + tail)/2;                //这里

 while( mid > head)

 {

  if (A[mid] == target) return mid;

  if(A[head] <= A[mid])

  {

   if (A[mid] >= target && A[head] <= target )

    tail = mid;

   else head = mid; //这里没有加1 ,但是while判断条件改了,所以while上得先让mid取值,又怕遗漏了正好是head,所以后面又加了

  }

  else

  {

   if (A[tail - 1] >= target && A[mid] <= target )

    head = mid;

   else tail = mid;

  }

  mid = (head + tail)/2;                     //改到了这里

 }

 if (A[mid] == target) return mid;  //加了这句话防止遗漏

 return -1;   


3)同时有加1和减1的版本

int search(int A[], int n, int target)

{

      int head,tail,mid;

 head = 0 ;

 tail = n - 1;

 if (tail == 0)

    if (A[head] == target) return 0;

 while(tail >= head)                                  //这里〉=只大于会漏tail - 1 = head时的情形,

 {

   mid = (head + tail)/2;

  if (A[mid] == target) return mid;

  if(A[head] <= A[mid])

  {

   if (A[mid] >= target && A[head] <= target )

    tail = mid - 1;

   else head = mid + 1;

  }

  else

  {

   if (A[tail] >= target && A[mid] <= target )

    head = mid + 1;

      else tail = mid - 1;

  }

 }

 return -1;

}


4. 在3的基础上

Follow up for "Search in Rotated Sorted Array":
What if duplicates are allowed?

Would this affect the run-time complexity? How and why?

Write a function to determine if a given target is in the array.


class Solution {

public:

    bool search(int A[], int n, int target) {

    int head,tail,mid;

 head = 0 ;

 tail = n - 1;

 if (tail == 0)

    if (A[head] == target) return true;

 while(tail >= head)

 {

   mid = (head + tail)/2;

  if (A[mid] == target) return true;

  if(A[head] < A[mid])

  {

   if (A[mid] >= target && A[head] <= target )

    tail = mid - 1;

   else head = mid + 1;

  }

  else if (A[head] > A[mid])

  {

   if (A[tail] >= target && A[mid] <= target )

    head = mid + 1;

      else tail = mid - 1;

  }

  else ++head;

 }

 return false;

    }

};



5.Median of Two Sorted Arrays

There 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)).

//这题未做出来,参考的答案

分析:

中值且已排序--〉找特定位置的数---〉分奇偶两种情形 --〉写出第一个函数

找某位置的数且已排序----〉比较两个序列的长度--〉归两种情况为一种(归并化便于分析)----〉两个数组截取(同时考虑边界情况) 



class Solution {

public:

    double findMedianSortedArrays(int A[], int m, int B[], int n) {

   

    int total = m + n;

    if (total & 0x1) // 判断奇偶,比%2效率高(深入理解计算机系统也讲过)

      return find_kth(A,m,B,n,total/2 + 1);

    else

        return (find_kth(A,m,B,n,total/2) + find_kth(A,m,B,n,total/2 + 1))/2;

    }

    static double find_kth(int A[],int m, int B[], int n, int k)

    {

        if (m > n) return find_kth(B,n,A,m,k);

        if (m == 0) return B[k - 1]; //这种保证m<=n的方法,可以让这种判断与下面 pa = min(k/2, m)对应, 只进行一次就可,不用分两种情况考虑,这是一种思维,两个情况下都是相同的多个子情况,用这种交换归为一种,厉害且思路清晰。

        if (k == 1) return min(A[0],B[0]);

       

        int pa = min( k/2 , m ) , pb = k - pa; //可不等于k/2, 另外前面的,m经过循环在变,若比k/2小的话

        if (A[pa - 1] < B[pb - 1])

            return find_kth(A + pa, m - pa, B, n, k - pa);

        else if (A[pa - 1] > B[pb - 1])

            return find_kth(A,m,B + pb, n - pb, k - pb);

        else

            return A[pa - 1]; //返回B[pb - 1]也可

       

    }

};


#include<iostream>

using namespace std;

double find_kth(int A[],int m, int B[], int n, int k)

    {

        if (m > n) return find_kth(B,n,A,m,k);

        if (m == 0) return B[k - 1]; //这种保证m<n的方法,可以让这种判断只进行一次就可

        if (k == 1) return min(A[0],B[0]);

        cout << "k : " << k << " m : " << m << endl;

        int pa = min( k/2 , m ) , pb = k - pa; //可不等于k/2, 另外前面的,m经过循环在变,若比k/2小的话

        cout << "pa : " << pa << " " << " pb : " << pb << endl;

        if (A[pa - 1] < B[pb - 1])

            return find_kth(A + pa, m - pa, B, n, k - pa);

        else if (A[pa - 1] > B[pb - 1])

            return find_kth(A,m,B + pb, n - pb, k - pb);

        else

            return A[pa - 1]; //返回B[pb - 1]也可

       

    }

double findMedianSortedArrays(int A[], int m, int B[], int n) {

 int total = m + n;

 if (total & 0x1) // 判断奇偶,比%2效率高(深入理解计算机系统也讲过)

   return find_kth(A,m,B,n,total/2 + 1);

 else

     return (find_kth(A,m,B,n,total/2) + find_kth(A,m,B,n,total/2 + 1))/2;

}

int main()

{

 int A[1] = {1};

 int B[6] = {2,3,4,5,6,7};

 cout << findMedianSortedArrays(A,1,B,6);

 

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值