编程积累3

124 阅读6分钟

1.合并两个有序链表

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
public:
    ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
        if(l1==NULL && l2==NULL)
            return NULL;
        if(l1==NULL && l2!=NULL)
            return l2;
        if(l2==NULL && l1!=NULL)
            return l1;
        ListNode* result=new ListNode();
        ListNode* p=result;
        while(l1 && l2)
        {
          ListNode* node=new ListNode();
          if(l2->val==l1->val)
          {
              
               node->val=l1->val;
               p->next=node;
               ListNode* node1=new ListNode();
               node1->val=l2->val;
               node->next=node1;
               p=node1;
               l1=l1->next;
               l2=l2->next;
              
               if(l1==NULL)
                  break;
                if(l2==NULL)
                  break;
          }
           else if(l2->val>l1->val)
           {
               node->val=l1->val;
               p->next=node; 
               p=node;
               l1=l1->next;
               if(l1==NULL)
                  break;
           }
          else
           {
               node->val=l2->val;
               p->next=node;
               p=node;
               l2=l2->next;
               if(l2==NULL)
                  break;
           }
        }
        if(l1) p->next=l1;
        if(l2) p->next=l2;
         return result->next;
    }
};

2.两两交换链表中的节点

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode(int x) : val(x), next(NULL) {}
 * };
 */
class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        if(head==NULL)
            return NULL;
        ListNode* result=NULL;
        if(head->next==NULL)
           return head;
        if(head->next->next==NULL)
           {
               result=head->next;
               head->next->next=head;
               head->next=NULL; 
               return result;
           }
           ListNode* first1=new ListNode(0);
            ListNode* first=first1;
           first->next=head;
           ListNode* node=head;
        while(node->next)
        {
            if(node->next->next==NULL)
               {
                 node->next->next=node;
                 first->next=node->next;
                 node->next=NULL;
                 break;
               }
           ListNode* second=node->next->next;
           first->next=node->next;
           first=node;
           node->next->next=node;
           node->next=second;
           node=second;
        }
        return first1->next;
    }
};

3.删除排序数组中的重复项

class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.empty())
          return 0;
       nums.erase(unique(nums.begin(),nums.end()),nums.end());
       return nums.size();
        
    }
};


class Solution {
public:
    int removeDuplicates(vector<int>& nums) {
        if(nums.empty())
          return 0;
          int i=0;
      for(int j=1;j<nums.size();j++)
      {
          if(nums[i]!=nums[j])
               i++;
             nums[i]=nums[j];  
      }
      return i+1; 
    }
};

4. 实现 strStr()

class Solution {
public:
    int strStr(string haystack, string needle) {
        if (needle == "")
		return 0;
	if (haystack == "")
		return -1;
	int size1 = haystack.size();
	int size2 = needle.size();
	int t = 0;
	int i = 0;
	for (; i < size1; i++)
	{
		if (haystack[i] == needle[t])
		{
			int a = i;
			if (t == size2-1 || i == size1-1)
				break;
			
			else if (haystack[i + 1] != needle[t + 1])
			{
				i = i - t;
				t = 0;
				
				continue;
			}
			else
		   t++;
		}
	}
	if (t + 1 < size2)
		return -1;
	if (size2 == 1 && i == 0 && haystack[0] != needle[0])
		return -1;
	if (size2 == 1 && i == size1 && haystack[i] != needle[0])
		return -1;
	if (t + 1 <size2 )
		return -1;
	return i - t ;
         
    }
};

5.给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符

class Solution {
public:
    int divide(int dividend, int divisor) {
        if(divisor==0)
          return INT_MAX;
        if(dividend==0)
          return 0;
         if(dividend==INT_MIN && divisor==1)
              return INT_MIN;
              if(dividend==INT_MIN && divisor==-1)
              return INT_MAX;
         long a=abs(dividend);
         long b=abs(divisor);
         long result=0;
         while(a>=b)
         {
             a=a-b;
             result++;
         } 
            
         if(dividend<0 && divisor>0)
            return (0-result);
         if(dividend>0 && divisor<0)
           return (0-result);
        if(dividend<0 && divisor<0)
               return result;
        return result;
    }
};

6.下一个排列

STL algorithmi算法s_sorted和is_sorted_until
该函数是測试范围内的元素是否已经有序
is_sorted_until
返回第一个破坏序列有序的元素迭代器

如果使用iter_swap函数,那么就可以进行交换了,先看一下函数的参数:
iter_swap(a,b);//a为一个迭代器,b为另一个迭代器。
顾名思义,iter_swap的功能就是交换两个迭代器的元素。

lower_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于或等
于num的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址
begin,得到找到数字在数组中的下标。

upper_bound( begin,end,num):从数组的begin位置到end-1位置二分查找第一个大于num
的数字,找到返回该数字的地址,不存在则返回end。通过返回的地址减去起始地址begin,
得到找到数字在数组中的下标。

reverse()会将区间[beg,end)内的元素全部逆序

组合数学中经常用到排列,这里介绍一个计算序列全排列的函数
:next_permutation(start,end),和prev_permutation(start,end)。这两个函数作用是一样的,区别就在于前者
求的是当前排列的下一个排列,后一个求的是当前排列的上一个排列
f1
class Solution {
public:
 void nextPermutation(vector<int>& nums) {
next_permutation(nums.begin(), nums.end());
}
};
f2
class Solution {
public:
    void nextPermutation(vector<int>& nums) {
        auto i = is_sorted_until(nums.rbegin(), nums.rend());
        if(i != nums.rend())
            iter_swap(i, upper_bound(nums.rbegin(), i, *i));
        reverse(nums.rbegin(), i);
    }
};
。

7.在排序数组中查找元素的第一个和最后一个位置

class Solution {
public:
    vector<int> searchRange(vector<int>& nums, int target) {
        vector<int> result={-1,-1};
        if(nums.empty())
          return result;
         auto first=lower_bound(nums.begin(),nums.end(),target);
         auto second=upper_bound(nums.begin(),nums.end(),target);
         int a,b;
         if(first!=nums.end())
        {
            if(*first==target)
              a=first-nums.begin();
            else
               return result;
        
          if(*(second-1)==target)
              b=second-1-nums.begin();
        result[0]=a;
        result[1]=b;
          }
        return result;    
    }
};

8.组合总和

深度优先搜索算法(Depth First Search,简称DFS):一种用于遍历或搜索树或图的算法。 沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过或者在搜寻时结点不满足条件,搜索将回溯到发现节点v的那条边的起始节点。整个进程反复进行直到所有节点都被访问为止。属于盲目搜索,最糟糕的情况算法时间复杂度为O(!n)。 回溯法(探索与回溯法)是一种选优搜索法,又称为试探法,按选优条件向前搜索,以达到目标。但当探索到某一步时,发现原先选择并不优或达不到目标,就退回一步重新选择,这种走不通就退回再走的技术为回溯法,而满足回溯条件的某个状态的点称为“回溯点”。

class Solution {
private:
     vector<vector<int>> result={};
     vector<int> tem={};
public:
    vector<vector<int>> combinationSum(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        if(candidates.empty() || target<=0)
           return result;
        sum_aux(0,target,candidates,candidates.size());
        return result;
      
    }
    void sum_aux(int index,int target,vector<int>& candidates,int size)
    {
        if(target==0)
        {
            result.push_back(tem);
            return;
        }
        else
        {
            for(int i=index;i<size && target-candidates[i]>=0;i++)
            {
                tem.push_back(candidates[i]);
                sum_aux(i,target-candidates[i],candidates,size);
                tem.pop_back();
            }
        }
    }
};

9.组合总和 II

class Solution {
private:
     vector<vector<int>> result={};
     vector<int> tem={};
public:
    vector<vector<int>> combinationSum2(vector<int>& candidates, int target) {
        sort(candidates.begin(),candidates.end());
        if(candidates.empty() || target<=0)
           return result;
        sum_aux(0,target,candidates,candidates.size());
        sort(result.begin(),result.end());
        result.erase(unique(result.begin(),result.end()),result.end());
        return result;
      
    }
    void sum_aux(int index,int target,vector<int>& candidates,int size)
    {
        if(target==0)
        {
            result.push_back(tem);
            return;
        }
        else
        {
            for(int i=index;i<size && target-candidates[i]>=0;i++)
            {
                tem.push_back(candidates[i]);
                sum_aux(i+1,target-candidates[i],candidates,size);
                tem.pop_back();
            }
        }
    }
};

10.旋转链表

class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        ListNode* res=NULL;
        if(head==NULL)
          return res;
        
        ListNode* first=head;
        if(head->next==NULL)
           return head;
        ListNode* end=head;
         ListNode* last;
         int len=1;
        while(end->next)
        {
            len++;
            last=end;
            end=end->next;
        }
        k=k%len;
        while(k>0)
        {
            end->next=first;
            last->next=NULL;
            first=end;
            end=last;
            ListNode* tem=first;
            while(tem->next)
        {
            last=tem;
            tem=tem->next;
        }
        k--;
        }
        return first;
        
    }
};

f2
class Solution {
public:
    ListNode* rotateRight(ListNode* head, int k) {
        if(head==0 || head->next==0) return head;
        
        int len = 1;
        ListNode *tail = head;
        while(tail->next){}
            ++len;
            tail = tail->next;
        }
        tail->next = head;

        if(k%=len){
            for(int i=0; i<len-k; ++i) tail = tail->next;
        }
        ListNode *res = tail->next;
        tail->next = 0;
        return res;
    }
};