双指针,前后指针法, 快排思路, leetcode

本文解析了多个经典算法问题,包括去除数组元素、奇偶数排序、链表倒数第K项、寻找和定值的两个数及链表回文判断等,并提供了详细的代码实现。

7. Remove Element

 
  My Submissions
  • Total Accepted: 146310
  • Total Submissions: 408505
  • Difficulty: Easy

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.

ac代码

class Solution {
public:
	int removeElement(vector<int>& nums, int val) {
		int len = nums.size();
			
		int left = 0;
		int right = len - 1;

		while (left <= right){
			while (left < len && nums[left] != val) //找到遇到的第一个val
			{
				left++;
			}

			while (right >= 0 && nums[right] == val) // 从后往前 找到第一个不是val的
			{
				right--;
			}
			if (left > right)
			{
				break;
			}
			// swap 上面的两个位置
			nums[left] = nums[right];
			nums[right] = val;
		}
		return left;
	}
};


-----



问题1: 奇偶数排序,使得奇数位于数组前半部分,偶数位于后半部分

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

bool isOddNum(int n)
{
	if(n % 2 == 1)
		return true;
	return false;
}

/* 返回 奇偶交界的位置 */
int OddEvenSort(int a[], int left, int right)
{
	if(left >= right)
		return -1;
	while(left < right)
	{
		while(isOddNum(a[left])) // 是奇数 头指针往后移动
			left ++;
		while(!isOddNum(a[right])) // 是偶数 尾指针往前移动
			right --;
		if(left < right)
		{
			swap(a[left] , a[right]); // a[left]为偶数, a[right]为奇数 交换
			left ++;
			right --;
		}
 	}
	return left;
}

int main()
{
	int a[] = {2, 8, 7, 1, 3, 5, 6, 4, 11};
	int n = 9;
	int pos = OddEvenSort(a,  0 , n - 1);
	printf("the count of Odd Number is %d\n", pos - 0);
	for(int i = 0; i < n - 1 ; i++)
	{
		printf("%d ", a[i]);
	}
	printf("%d\n", a[n - 1]);
	return 0;
}

问题2: 求链表的倒数第k项

题目参考:http://blog.youkuaiyun.com/qq_26437925/article/details/49488049

#include <cstdio>  
#include <sstream>  
#include <cstring>  
#include <iostream>
#include <string>
#include <vector>
#include <list>
#include <algorithm>

using namespace std;

typedef struct node
{
	int data;
	struct node *next;
}lnode;

lnode *create_node(int data)
{
	lnode *tmp = (lnode *)malloc(sizeof(lnode));
	tmp->data = data;
	tmp->next = NULL;
	return tmp;
}

int k ;

int main()
{
        //freopen("in.txt", "r", stdin);
	scanf("%d" , &k) ;
	int tmp ;
	int len = 0;
	lnode *head, *tail;
	while(scanf("%d" , &tmp) != EOF && tmp >= 0)
	{
		if(len == 0){
			head = create_node(tmp);
			tail = head;
		}else{
			lnode *node_tmp = create_node(tmp);
			tail->next = node_tmp;
			tail = node_tmp;
		}
		len ++;
	}
	if(k <= 0 || k > len)
		printf("NULL\n") ;
	else{
		// 令p , q相距为k
		lnode *p = head;
		lnode *q = head;
		for(int i = 0; i < k; i ++)
			q = q->next;
		// q移动到链表尾部,则p移动到倒数第k个位置
		while(q != NULL)
		{
			p = p->next;
			q = q->next;
		}
		printf("%d\n", p->data);
	}
	return 0 ;
}


寻找和为定值的两个数:http://blog.youkuaiyun.com/qq_26437925/article/details/48179185


荷兰国旗:

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <string>
using namespace std;

int main()
{
	char s[] = "0121120210";
	int len = strlen(s);
	
	int current = 0, begin = 0 , end = len -1;
	while(current <= end)
	{
		if(s[current] == '0') {
			//char tmp = s[current];
			//s[current] = s[begin];
			//s[begin] = tmp;
			swap(s[current], s[begin]);
			begin ++;
			current ++;
		} else if(s[current] == '1') {
			current ++;
		} else {
			//char tmp = s[current];
			//s[current] = s[end];
			//s[end] = tmp;
			swap(s[current], s[end]);
			end --;
		}
	}
	puts(s);
	return 0;
}



leetcode     https://leetcode.com/problems/sort-colors/

ac代码

class Solution {
public:
	void sortColors(vector<int>& nums) {
		int len = nums.size();

		int begin = 0; // 0与begin交换
		int end = len - 1; // 2与end交换 
		int current = 0; // 用来遍历

		while (current <= end)
		{
			if (nums[current] == 0)
			{
				swap(nums[begin], nums[current]);
				current++;
				begin++;
			}
			else if (nums[current] == 2)
			{
				swap(nums[end], nums[current]);
				//current++; 这里current 变成了原来的end ,不能current++
				end--;
			}
			else // 1
			{ 
				current++;
			}
		}
	}
};




问题4  (链表回文判断)

    对于一个链表,请设计一个时间复杂度为O(n),额外空间复杂度为O(1)的算法,判断其是否为回文结构。

给定一个链表的头指针A,请返回一个bool值,代表其是否为回文结构。保证链表长度小于等于900。

测试样例:
1->2->2->1
返回:true
/*
struct ListNode {
    int val;
    struct ListNode *next;
    ListNode(int x) : val(x), next(NULL) {}
};*/
class PalindromeList {
public:
	bool chkPalindrome(ListNode* A) {
		// write code here
		if (A == NULL)
			return false;

		if(A->next == NULL)
			return true;
		
		// 找到中间节点
		ListNode* p = A;
		ListNode* q = A;
		while (q != NULL)
		{
			p = p->next;// p移动一次
			q = q->next;// q移动两次
			if (q != NULL)
			{
				q = q->next;
			}
		}

		int len = 0;
		//反转后面的节点
		ListNode* head = NULL;
		while (p != NULL)
		{
			q = p->next;
			if (head != NULL)
			{
				p->next = head;
				head = p;
			}
			else{
				head = p;
			}
			len++;
			p = q;
		}

		// 逐一比较
		p = A;
		q = head;
		for (int i = 0; i < len; i++)
		{
			if (p->val != q->val)
				return false;
			p = p->next;
			q = q->next;
		}
		return true;
	}
};

234. Palindrome Linked List
题目地址:https://leetcode.com/problems/palindrome-linked-list/


Longest Substring Without Repeating Characters (leetcode)

ac代码,采用了两个指针和一个map结构
class Solution {
public:
	int lengthOfLongestSubstring(string s) {
		int len = s.size();
		vector<int> mp(256, -1);

		int maxLen = 0;
		
		int sta = 0, en = 0;
		int curLen = 0;
		while (en < len)
		{
			if (mp[s[en]] == -1)
			{
				mp[s[en]] = 1;
				en++;
			}
			else{
				while (s[sta] != s[en])
				{
					mp[s[sta]] = -1;
					sta++;
				}
				sta++;
				en++;
			}
			curLen = en - sta;
			maxLen = max(maxLen, curLen);
		}
		return maxLen;
	}
};




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值