找出数组中重复的数字。
在一个长度为 n 的数组 nums 里的所有数字都在 0~n-1 的范围内。数组中某些数字是重复的,但不知道有几个数字重复了,也不知道每个数字重复了几次。请找出数组中任意一个重复的数字。
void Swap(int*a,int*b)
{
int c=*a;
*a=*b;
*b=c;
}
//利用快速排序
// //单趟排序 左右指针法
// int PartSort(int *a,int begin,int end)
// {
// int key=a[end];
// int tmp=end;
// while(begin<end){
// while(begin<end&&a[begin]<=key)
// begin++;
// while(begin<end&&a[end]>=key)
// end--;
// Swap(&a[begin],&a[end]);
// }
// Swap(&a[begin],&a[tmp]);
// return begin;
// }
// //单趟排序 挖坑法
// int PartSort(int *a,int begin,int end)
// {
// int key=a[end];//坑
// while(begin<end)
// {
// while(begin<end&&a[begin]<=key)//右边找大
// begin++;
// a[end]=a[begin];//找到打的扔到右边的坑里去,同时begin形成新的坑位
// while(begin<end&&a[end]>=key)//左边找小
// end--;
// a[begin]=a[end];//找到小的扔到左边的坑位中去,同时end形成新的坑
// }
// a[begin]=key;
// return begin;
// }
// //单趟排序 前后指针法
// int PartSort(int *a,int begin,int end)
// {
// //设定 cur end 与prev
// //cur指向开始,prev指向开始的前一个数字。end指向最后一个数字!
// //cur向后移动,遇到大于end位置的数字,prev++。当cur=prev不做反应。否则狡猾cur位置与prev位置的数字
// //当cur==end;++prev 交换prev位置与end位置的数字
// int cur=begin;
// int key=a[end];
// int prev=begin-1;
// while(cur<end){
// if(a[cur]>key&&++prev!=cur)//当第一个条件为假的时候便不会执行第二个条件,prev也就不会++;
// Swap(&a[prev],&a[cur]);
// ++cur;
// }
// ++prev;
// Swap(&a[prev],&a[end]);
// return prev;
// }
// void QuickSort(int *a,int begin,int end)
// {
// if(begin>=end)
// return;
// int keyindex=PartSort(a,begin,end);
// QuickSort(a,begin,keyindex-1);
// QuickSort(a,keyindex+1,end);
// }
int findRepeatNumber(int* nums, int numsSize){
// //进行直接插入排序
// //而后比较连续的数字即可
//哈希排序
int gap=numsSize;
while(gap>1){
gap=gap/3+1;
for(int i=0;i<numsSize-gap;i++)
{
int end=i;
int tmp=nums[end+gap];
while(end>=0){
if(nums[end]>tmp){
nums[end+gap]=nums[end];
end-=gap;
}
else
break;
}
nums[end+gap]=tmp;
}
}
// //选择排序
// int begin=0;
// int end=numsSize-1;
// while(begin<end)
// {
// int mini=begin;
// int maxi=end;
// for(int i=0;i<=end;i++){
// if(nums[i]<nums[mini])
// mini=i;
// if(nums[i]>nums[maxi])
// maxi=i;
// }
// Swap(&nums[begin],&nums[mini]);
// if(begin==maxi)
// maxi=mini;
// Swap(&nums[end],&nums[maxi]);
// begin++;
// end--;
// }
// //冒泡排序
// for(int end=numsSize-1;end>0;end--){
// for(int i=0;i<end;i++){
// if(nums[i]>nums[i+1])
// swap(&nums[i],&nums[i+1]);
// }
// }
// QuickSort(nums,0,numsSize-1);
for(int i=0;i<numsSize;i++)
{
if(nums[i]==nums[i+1])
return nums[i];
}
return -1;
}
请实现一个函数,把字符串 s
中的每个空格替换成"%20"。
class Solution {
public:
string replaceSpace(string s) {
string linjia;
for(auto c:s)
{
if(c==' ')
{
linjia.push_back('%');
linjia.push_back('2');
linjia.push_back('0');
}
else
{
linjia.push_back(c);
}
}
return linjia;
}
};
输入一个链表的头节点,从尾到头反过来返回每个节点的值(用数组返回)。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
vector<int> reversePrint(ListNode* head) {
vector<int>res;
for(ListNode* i=head;i!=NULL;i=i->next)
res.push_back(i->val);
reverse(res.begin(),res.end());
return res;
}
};
// vector<int>res;
// if(head==NULL){
// res.push_back(NULL);
// return res;}
// else if(head->next==NULL){
// res.push_back(head->val);
// return res;}
// ListNode *p1=head,*p2=NULL,*p3=p1->next;
// while(p1){
// p1->next=p2;
// p2=p1;
// p1=p3;
// if(p3)
// p3=p3->next;
// }
// while(p2){
// res.push_back(p2->val);
// p2=p2->next;
// }
// return res;
// }
// };
用两个栈实现一个队列。队列的声明如下,请实现它的两个函数 appendTail 和 deleteHead ,分别完成在队列尾部插入整数和在队列头部删除整数的功能。(若队列中没有元素,deleteHead 操作返回 -1 )
class CQueue {
public:
stack<int>a;
stack<int>b;
CQueue() {
}
void appendTail(int value) {
a.push(value);
}
int deleteHead() {
if(a.empty()&&b.empty())
return -1;
if(b.empty()&&!a.empty())
{
while(!a.empty())
{
b.push(a.top());
a.pop();
}
}
int cur=b.top();
b.pop();
return cur;
}
};
/**
* Your CQueue object will be instantiated and called as such:
* CQueue* obj = new CQueue();
* obj->appendTail(value);
* int param_2 = obj->deleteHead();
*/
给定单向链表的头指针和一个要删除的节点的值,定义一个函数删除该节点。
返回删除后的链表的头节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* deleteNode(struct ListNode* head, int val){
struct ListNode* cur=head->next;
struct ListNode* prev=head;
if(head==NULL)
return;
if(head->next==NULL)
return;
if(head->val==val)
return head->next;
else{
while(cur->val!=val){
cur=cur->next;
prev=prev->next;
}
prev->next=cur->next;
return head;
}
// while(cur){
// if(cur->val==val)
// break;
// prev=cur;
// cur=cur->next;
// }
// if(cur==head){//处理删除节点在头部的情况
// head=cur->next;
// }
// if(cur->next==NULL){//处理删除节点在尾部的情况
// prev->next=NULL;
// }
// else{
// prev->next=cur->next;
// }
// return head;
}
输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如,一个链表有6个节点,从头节点开始,它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个节点是值为4的节点
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
typedef struct ListNode Node;
struct ListNode* getKthFromEnd(struct ListNode* head, int k){
if(head==NULL||head->next==NULL)
{
return head;
}
Node *cur=head;
Node *prev=NULL;
Node *p=cur->next;
while(cur)
{
cur->next=prev;
prev=cur;
cur=p;
if(p)
p=p->next;
}
Node *r=prev;
while(k-1){
prev=prev->next;
k--;
}
prev->next=NULL;
Node *p1=r;
Node *p2=NULL;
Node *p3=r->next;
while(p1)
{
p1->next=p2;
p2=p1;
p1=p3;
if(p3)
p3=p3->next;
}
return p2;
}
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
if(head==0||head->next==0)
return head;
struct ListNode*prev=NULL;
struct ListNode *cur=head;
struct ListNode *p=cur->next;
while(cur){
cur->next=prev;
prev=cur;
cur=p;
if(p)
p=p->next;
}
return prev;
}
输入两个递增排序的链表,合并这两个链表并使新链表中的节点仍然是递增排序的。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* mergeTwoLists(struct ListNode* l1, struct ListNode* l2){
struct ListNode* head=NULL;
struct ListNode* lite=NULL;
if(l1==NULL)//开始就判空
return l2;
if(l2==NULL)
return l1;
while(l1&&l2)
{
if(l1->val<l2->val)
{
if(lite==NULL)
{
head=lite=l1;
}
else{
lite->next=l1;
lite=l1;
}
l1=l1->next;
}
else
{
if(lite==NULL)
{
head=lite=l2;
}
else{
lite->next=l2;
lite=l2;
}
l2=l2->next;
}
}
if(l1)
{
lite->next=l1;
}
else if(l2)
{
lite->next=l2;
}
return head;
}
定义栈的数据结构,请在该类型中实现一个能够得到栈的最小元素的 min 函数在该栈中,调用 min、push 及 pop 的时间复杂度都是 O(1)。
class MinStack {
public:
stack<int>a;
stack<int>b;//这是一个辅助栈
/** initialize your data structure here. */
MinStack() {
}
void push(int x) {
a.push(x);
if(b.empty()||b.top()>=x)
b.push(x);
}
void pop() {
if(a.top()==b.top())
b.pop();
a.pop();
}
int top() {
return a.top();
}
int min() {
return b.top();
}
};
/**
* Your MinStack object will be instantiated and called as such:
* MinStack* obj = new MinStack();
* obj->push(x);
* obj->pop();
* int param_3 = obj->top();
* int param_4 = obj->min();
*/
输入两个链表,找出它们的第一个公共节点。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
if(headA==NULL||headB==NULL)
return NULL;
ListNode* cur=headA;
ListNode* pur=headB;
while(cur!=pur)
{
cur=cur==NULL?headB:cur->next;
pur=pur==NULL?headA:pur->next;
}
return cur;
}
};