标签:linked thread 单链表 time iso with ott 部分 自己
数组是n(N>=1)个相同数据类型的数据元素的有限序列;
数组是具有固定格式和数量的数据有序集;
注意:在数据上不能进行插入、删除数据元素等操作
数组的操作:
数组是一种随机存储结构
有两种存储方法是:
C#支持一维数组、多维数组、交错数组
数组在托管堆上分配空间,是引用类型;
常用方法
public abstract class Array : ICloneable, IList, ICollection, IEnumerable
{
public bool IsFixedSize{get;}
public iint Length{get;}
//获取 Array 的秩(维数)。
public int Rank { get; }
//实现的 IComparable 接口,在.Array 中搜索特定元素。
public static int BinarySearch(Array array, object value);
//实现的 IComparable<T>泛型接口,在 Array 中搜索特定元素。
public static int BinarySearch<T>(T[] array, T value);
//实现 IComparable 接口,在 Array 的某个范围中搜索值。
public static int BinarySearch(Array array, int index, int length,object value);
//实现的 IComparable<T>泛型接口,在 Array 中搜索值。
public static int BinarySearch<T>(T[] array, int index, int length, T value);
//Array 设置为零、false 或 null,具体取决于元素类型。
public static void Clear(Array array, int index, int length);
//System.Array 的浅表副本。
public object Clone();
//从第一个元素开始复制 Array 中的一系列元素 //到另一 Array 中(从第一个元素开始)。
public static void Copy(Array sourceArray, Array destinationArray, int length);
//将一维 Array 的所有元素复制到指定的一维 Array 中。
public void CopyTo(Array array, int index);
//创建使用从零开始的索引、具有指定 Type 和维长的多维 Array。
public static Array CreateInstance(Type elementType, params int[] lengths);
//返回 ArrayIEnumerator。
public IEnumerator GetEnumerator();
//获取 Array 指定维中的元素数。
public int GetLength(int dimension);
//获取一维 Array 中指定位置的值。
public object GetValue(int index);
//返回整个一维 Array 中第一个匹配项的索引。
public static int IndexOf(Array array, object value);
//返回整个.Array 中第一个匹配项的索引。
public static int IndexOf<T>(T[] array, T value);
//返回整个一维 Array 中后一个匹配项的索引。
public static int LastIndexOf(Array array, object value);
//反转整个一维 Array 中元素的顺序。
public static void Reverse(Array array);
//设置给一维 Array 中指定位置的元素。
public void SetValue(object value, int index);
//对整个一维 Array 中的元素进行排序。
public static void Sort(Array array);
}
编写一段代码,要求输入一个整数N,用动态数组A来存放2~N之间所有5或7的倍数,输出该数组。
C#代码
static void Main(string[] args)
{
Console.WriteLine("N=");
string str = Console.ReadLine();
int n=0;
if (int.TryParse(str, out n))
{
DArray<int> dArr = new DArray<int>();
int j = 0;
for (int i = 2; i <= n; i++)
{
if (i%5 == 0 || i%7 == 0)
{
dArr.Append(i);
}
}
Console.Write(dArr);
}
}
https://leetcode-cn.com/problems/toeplitz-matrix/
如果一个矩阵的每一方向由左上到右下的对角线上具有相同元素,那么这个矩阵是托普利茨矩阵。
给定一个M x N的矩阵,当且仅当它是托普利茨矩阵时返回True。
public class Solution {
public bool IsToeplitzMatrix(int[][] matrix)
{
for(int i = 0; i < matrix.Length - 1; i++)
{
for(int j = 0; j < matrix[i].Length - 1; j++)
{
if(matrix[i][j] != matrix[i+1][j+1])
{
return false;
}
}
}
return true;
}
}
https://leetcode-cn.com/problems/3sum/
给定一个包含 n 个整数的数组nums
,判断nums
中是否存在三个元素a,b,c
,使得a + b + c = 0
?找出所有满足条件且不重复的三元组。
注意:答案中不可以包含重复的三元组。
public class Solution {
public IList<IList<int>> ThreeSum(int[] nums) {
Array.Sort(nums);
IList<IList<int>> all = new List<IList<int>>();
int len = nums.Length;
int x = 0, y, z;
List<int> li;
for (; x < len-1; x++)
{
if (nums[x] > 0)
break;
if (x > 0 && nums[x] == nums[x - 1])
continue;
z = x + 1;
y=len - 1;
while (z < y )
{
int num = nums[x] + nums[y] + nums[z];
if (num > 0)
while (y>z && nums[y] == nums[--y]) ;
else if (num < 0)
while ( y>z && nums[z] == nums[++z]) ;
else
{
li = new List<int>();
li.Add(nums[x]);
li.Add(nums[z]);
li.Add(nums[y]);
all.Add(li);
while(y>x && nums[y]==nums[--y]);
}
}
}
return all;
}
}
顺序存储的线性表叫顺序表,
表中存储单元连续,C#中用数组来实现
链式存储的线性表是链表,存储单元不一定连续
在一个节点中,还有数据域存放数据元素本身信息,还有引用域存储其相邻的数据元素的地址信息。
https://leetcode-cn.com/problems/merge-two-sorted-lists/
将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
public class Solution {
public ListNode MergeTwoLists(ListNode l1, ListNode l2) {
var newList = new ListNode(0);
//链表的节点
var node = newList;
while(l1 != null && l2 != null)
{
if(l1.val <l2.val)
{
node.next = l1;
l1 = l1.next;
}
else
{
node.next = l2;
l2 = l2.next;
}
//更新节点
node = node.next;
}
if(l1 != null)
node.next = l1;
if(l2 != null)
node.next = l2;
return newList.next;
}
}
https://leetcode-cn.com/problems/remove-nth-node-from-end-of-list/
给定一个链表,删除链表的倒数第?n?个节点,并且返回链表的头结点。
public ListNode RemoveNthFromEnd(ListNode head, int n) {
int len = 1;
var aNode = head;
var bNode = head;
while(aNode.next != null)
{
if(len > n)
{
bNode = bNode.next;
}
aNode = aNode.next;
len++;
}
if(n ==len) return head.next;
bNode.next = bNode.next.next;
return head;
}
https://leetcode-cn.com/problems/rotate-list/
给定一个链表,旋转链表,将链表每个节点向右移动k个位置,其中k是非负数。
public ListNode RotateRight(ListNode head, int k)
{
if (head == null || head.next == null) return head;
ListNode aNode = head;
int len = 0;
while(k > 0 && aNode != null)
{
aNode = aNode.next;
len++;
k--;
}
if(aNode == null)
{
k = k % len; //余数
aNode = head;
while(k > 0)
{
aNode = aNode.next;
k--;
}
}
ListNode bNode = head;
if(k == 0)
{
while(aNode.next != null)
{
aNode = aNode.next;
bNode = bNode.next;
}
}
aNode.next = head;
head = bNode.next;
bNode.next = null;
return head;
}
是操作限定在表的尾端进行的线性表
表为进行插入、删除等操作
表尾称为栈顶top,另一端固定叫栈底bottom
没有数据元素的栈叫空栈Empty Stack
S = (a1,a2,...,an)
a1 栈底元素
an栈顶元素
出入栈顺序:先进后出,后进先出
S=(D,R) D是数据元素的有限集合,R是数据元素之间关系的有限集合
栈的操作:栈顶插入、删除元素,取栈顶元素,判断栈是否为空
用连续的存储空间来存储栈中的数据元素,称为顺序栈 Sequence Stack 。一维数据存放顺序栈中的数据元素。
public class SeqStack<T>:IStack<T>{
private int maxsize;
private T[] data; //顺序栈中的数据元素
private int top; //顺序栈的栈顶
}
链式存储的栈成为链栈Linked Stack
通常用单链表来表示,是单链表的简化
栈顶设在链表头部,不需要头结点
链栈节点类Node
public class Node<T>
{
private T data; //数据域
private Node<T> next; //引用域
}
链栈类LinkStack
public class LinkStack<T>:IStack<T>{
private Node<T> top; //栈顶指示器
private int num; // 栈中结点的个数
}
链栈的基本操作:
一个算法直接调用自己或间接调用自己,就称这个算法是诋毁Recursive.
调用方式不同:直接递归Direct Recursion、简介递归 Indirect Recursion
必须有两个部分:初始部分、递归部分
递归调用的理解:通过一系列的自身调用,达到某一终止条件后,在按照嗲用路线逐步返回。
根据要求完成车辆重排的程序代码
假设一列货运列车共有n
节车厢,每节车厢将停放在不同的车站。假定n
个车站的编号分别为1
至n
,货运列车按照第n
站至第1
站的次序经过这些车站。车厢的编号与它们的目的地相同。为了便于从列车上卸掉相应的车厢,必须重新排列车厢,使各车厢从前至后按编号1
至n
的次序排列。当所有的车厢都按照这种次序排列时,在每个车站只需卸掉最后一节车厢即可。
我们在一个转轨站里完成车厢的重排工作,在转轨站中有一个入轨、一个出轨和k
个缓冲铁轨(位于入轨和出轨之间)。图(a)给出一个转轨站,其中有k
个(k=3
)缓冲铁轨H1
,H2
?和H3
。开始时,n
节车厢的货车从入轨处进入转轨站,转轨结束时各车厢从右到左按照编号1
至n
的次序离开转轨站(通过出轨处)。在图(a)中,n=9
,车厢从后至前的初始次序为5,8,1,7,4,2,9,6,3
。图(b)给出了按所要求的次序重新排列后的结果。
编写算法实现火车车厢的重排,模拟具有n
节车厢的火车“入轨”和“出轨”过程。
class Program
{
static void Main(string[] args)
{
int[] h = new int[]{5, 3, 6, 8, 4, 1, 2,9, 7};
int k = 3;
bool result = Stack.RailRoad(h, k);
while (result == false)
{
Console.WriteLine("缓冲轨道数量不满足使用,请输入数字扩充。");
k = k + Convert.ToInt32(Console.ReadLine());
result = Stack.RailRoad(h, k);
}
}
}
/// <summary>
/// 车厢重排算法
/// 使用入出栈
/// </summary>
public static class Stack
{
public static bool RailRoad(int[] h,int k)
{
int n = h.Length;
int noOut = 1;
Stack<int>[] stacks = new Stack<int>[k];
for (int i = 0; i < k; i++)
stacks[i] = new Stack<int>();
for(int i = 0; i<n;i++)
{
if (noOut == h[i])
{
//符合出轨序号,直接进入出轨
Console.WriteLine("直接出轨:车厢号{0}直接出轨", h[i]);
noOut++;
//判断缓冲轨是否有可以出轨车厢
while (OutPut(stacks, noOut))
noOut++;
}
else
{
//存入缓冲轨
if (!Hold(stacks, h[i]))
return false;
}
}
return true;
}
#region 车厢入缓冲轨
/// <summary>
/// 车厢入缓冲轨
/// </summary>
/// <param name="stacks">缓冲轨栈</param>
/// <param name="no">车厢号</param>
/// <returns></returns>
static bool Hold(Stack<int>[] stacks, int no)
{
int m = 0; //最佳缓冲轨,默认第一轨
int top = 0; //最佳缓冲轨栈顶元素,默认第一轨栈顶元素
for (int i = 0; i < stacks.Length; i++)
{
if (stacks[i].Count == 0)
{
m = top > no ? m: i;
top = no;
break;
}
else
{
if (no < stacks[i].Peek())
{
if ( top == 0 || top > stacks[i].Peek())
{
top = stacks[i].Peek();
m = i;
}
}
}
}
if (top == 0)
return false;
stacks[m].Push(no);
Console.WriteLine("入缓冲轨:车厢号{0}入缓冲轨{1}", no, m + 1);
return true;
}
#endregion
#region 车厢出缓冲轨
/// <summary>
/// 车厢出缓冲轨
/// </summary>
/// <param name="stacks"></param>
/// <param name="no"></param>
/// <returns>是否有车厢从缓冲轨出</returns>
static bool OutPut(Stack<int>[] stacks,int no)
{
for (int i = 0; i < stacks.Length; i++)
{
if (stacks[i].Count == 0)
continue;
if(no == stacks[i].Peek())
{
stacks[i].Pop();
Console.WriteLine("出缓冲轨:车厢号{0}出缓冲轨{1}", no, i + 1);
return true;
}
}
return false;
}
#endregion
}
public interface IQueu<T>{
int GetLength();
bool IsEmpty();
void Clear();
void In(T item); //将值为item的新数据元素添加到队尾
T Out(); //将队头元素从队列中取出,队列发生变化
T GetFront(); //取队头元素的值,队列不发生变化
}
用一片连续的存储空间来存储队列中的数据元素,这样的队列成为顺序队列 Sequence Queue ,类似与顺序栈。
将顺序队列堪称时首位相接的循环结构,头尾指示器的关系不变
public class CSeqQueue<T>:IQueue<T>{
private int maxsize;
private T[] data;
private int front;
private int rear;
public int GetLength()
{
return (rear - front + maxsize)%maxsize;
}
public void Clear()
{
front = rear = -1;
}
public bool IsEmpty()
{
if(front == rear)
{
return true;
}
else
{
return false;
}
}
public bool IsFull()
{
// (rear + 1)% maxsize 等于 front
}
public void In(T item)
{
// data[++rear] = item;
}
public T Out()
{
T tmp = default(T);
if(IsEmpty())
{
Console.WriteLine("Queue is empty");
return tmp;
}
tmp = data[++front];
return tmp;
}
public T GetFront()
{
//IsEmpty判断
return data[front+1];
}
队列的另一种存储方式时链式存储,称为链队列 Linked Queue
通常用单链表来表示,它的实现时单链表的简化
链队列长度:GetLength() //return num
清空操作:Clear() //front = rear = null; num = 0;
链队列是否为空 IsEmpty() // front == rar && num == 0
入队操作:In()
Node<T> q = new Node<T>(item);
if(rear == null)
{
front = rear = q;
}
else
{
rear.Next = q;
rear = q;
}
num++;
public T Out()
{
if(IsEmpty())
{
Console.WriteLine("Queue is empty");
return default(T);
}
Node<T> p = front;
front = front.Next;
--num;
return p.Data;
}
目前,在以银行营业大厅为代表的窗口行业中大量使用排队(叫号)系统,该系统完全模拟了人群排队全过程,通过取票进队、排队等待、叫号服务等功能,代替了人们站队的辛苦。
排队叫号软件的具体操作流程为:
顾客取服务序号
当顾客抵达服务大厅时,前往放置在入口处旁的取号机,并按一下其上的相应服务按钮,取号机会自动打印出一张服务单。单上显示服务号及该服务号前面正在等待服务的人数。
服务员工呼叫顾客 服务员工只需按一下其柜台上呼叫器的相应按钮,则顾客的服务号就会按顺序的显示在显示屏上,并发出“叮咚”和相关语音信息,提示顾客前往该窗口办事。当一位顾客办事完毕后,柜台服务员工只需按呼叫器相应键,即可自动呼叫下一位顾客。
编写程序模拟上面的工作过程,主要要求如下:
程序运行后,当看到“请点击触摸屏获取号码:”的提示时,只要按回车键,即可显示“您的号码是:XXX,您前面有YYY位”的提示,其中XXX是所获得的服务号码,YYY是在XXX之前来到的正在等待服务的人数。
用多线程技术模拟服务窗口(可模拟多个),具有服务员呼叫顾客的行为,假设每个顾客服务的时间是10000ms,时间到后,显示“请XXX号到ZZZ号窗口!”的提示。其中ZZZ是即将为客户服务的窗口号。
IQueue接口、循环顺序队列、链队列
interface IQueue<T>
{
int GetLength();
bool IsEmpty();
void Clear();
void In(T item);
T Out();
T GetFront();
}
#region 循环顺序队列
/// <summary>
/// 循环顺序队列
/// </summary>
/// <typeparam name="T"></typeparam>
public class CSeqQueue<T> : IQueue<T>
{
private int maxsize;
private T[] data;
private int front;
private int rear;
public T this[int index]
{
get
{
return data[index];
}
set
{
data[index] = value;
}
}
public int MaxSize { get { return maxsize; } set { maxsize = value; } }
public int Front { get { return front; } set { front = value; } }
public int Rear { get { return rear; } set { rear = value; } }
public CSeqQueue(int size)
{
data = new T[size];
maxsize = size;
front = rear = -1;
}
public int GetLength()
{
return (rear - front + maxsize) % maxsize;
}
public void Clear()
{
front = rear = -1;
}
public bool IsEmpty()
{
if (front == rear)
return true;
return false;
}
public bool IsFull()
{
if ((rear + 1) % maxsize == front)
return true;
return false;
}
public void In(T item)
{
if (IsFull())
{
Console.WriteLine("Queue is Full");
return;
}
data[++rear] = item;
}
public T Out()
{
T tmp = default(T);
if (IsEmpty())
{
Console.WriteLine("Queue is empty");
return tmp;
}
tmp = data[++front];
return tmp;
}
public T GetFront()
{
if (IsEmpty())
{
Console.WriteLine("Queue is empty");
return default(T);
}
return data[front + 1];
}
}
#endregion
#region 链队列结点类
/// <summary>
/// 链队列结点类
/// </summary>
/// <typeparam name="T"></typeparam>
public class Node<T>
{
private T data;
private Node<T> next;
public Node(T val, Node<T> p)
{
data = val;
next = p;
}
public Node(Node<T> p)
{
next = p;
}
public Node(T val)
{
data = val;
next = null;
}
public Node()
{
data = default(T);
next = null;
}
public T Data
{
get { return data; }
set { data = value; }
}
public Node<T> Next
{
get { return next; }
set { next = value; }
}
}
#endregion
#region 链队列
/// <summary>
/// 链队列
/// </summary>
/// <typeparam name="T"></typeparam>
public class LinkQueue<T> : IQueue<T>
{
private Node<T> front;
private Node<T> rear;
private int num; //队列结点个数
public Node<T> Front { get { return front; } set { front = value; } }
public Node<T> Rear { get { return rear; } set { rear = value; } }
public int Num { get { return num; } set { num = value; } }
public LinkQueue()
{
front = rear = null;
num = 0;
}
public int GetLength()
{
return num;
}
public void Clear()
{
front = rear = null;
num = 0;
}
public bool IsEmpty()
{
if((front == rear) && (num == 0))
return true;
return false;
}
public void In(T item)
{
Node<T> q = new Node<T>(item);
if(rear == null)
{
front = rear = q;
}
else
{
rear.Next = q;
rear = q;
}
num++;
}
public T Out()
{
if(IsEmpty())
{
Console.WriteLine("Queue is empty");
return default(T);
}
Node<T> p = front;
front = front.Next;
if(front == null)
{
rear = null;
}
--num;
return p.Data;
}
public T GetFront()
{
if(IsEmpty())
{
Console.WriteLine("Queue is empty");
return default(T);
}
return front.Data;
}
}
#endregion
public interface IBankQueue:IQueue<int>
{
int GetCallNum();
int MaxSize { get; }
}
public class LinkBankQueue:LinkQueue<int>,IBankQueue
{
public int CallNumber { get; set; }
public int MaxSize { get; }
public LinkBankQueue()
{
MaxSize = default(int);
CallNumber = 0;
}
public int GetCallNum()
{
if(IsEmpty() && CallNumber ==0)
{
CallNumber = 1;
}
else
{
CallNumber++;
}
return CallNumber;
}
}
public class CSeqBankQueue:CSeqQueue<int>,IBankQueue
{
public int Callnumber { get; private set; }
//public int MaxSize { get; }
public CSeqBankQueue(int size):base(size)
{
Callnumber = 0;
}
public int GetCallNum()
{
if (IsEmpty() && Callnumber == 0)
Callnumber = 1;
else
Callnumber++;
return Callnumber;
}
}
public class ServiceWindow
{
public IBankQueue Bankq { get; set; }
public void service()
{
while(true)
{
lock(Bankq)
{
Thread.Sleep(10000);
if(!Bankq.IsEmpty())
{
Console.WriteLine();
Console.WriteLine("{2}:请{0}号到{1}号窗口", Bankq.GetFront(), Thread.CurrentThread.Name, DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
Bankq.Out();
}
}
}
}
}
main
class Program
{
/// <summary>
/// 银行排队叫号
/// </summary>
/// <param name="args"></param>
static void Main(string[] args)
{
try
{
IBankQueue bankQueue = null;
Console.WriteLine("请选择存储结构类型:1.顺序队列,2.链队列");
string flag = Console.ReadLine();
switch(flag)
{
case "1":
Console.WriteLine("请输入队列可容纳人数:");
int count = Convert.ToInt32(Console.ReadLine());
bankQueue = new CSeqBankQueue(count);
break;
case "2":
bankQueue = new LinkBankQueue();
break;
}
int windowsnum = 5;
ServiceWindow[] serviceWindows = new ServiceWindow[windowsnum];
Thread[] serviceThread = new Thread[windowsnum];
for (int i = 0; i < windowsnum; i++)
{
serviceWindows[i] = new ServiceWindow();
serviceWindows[i].Bankq = bankQueue;
serviceThread[i] = new Thread(serviceWindows[i].service);
serviceThread[i].Name = (i + 1).ToString();
serviceThread[i].Start();
}
while(true)
{
Console.WriteLine("点击获取号码:");
Console.ReadLine();
if (bankQueue != null && (bankQueue.GetLength() < bankQueue.MaxSize || flag == "2"))
{
int callnumber = bankQueue.GetCallNum();
Console.WriteLine("{2}:您的号码时:{0},前面还有{1}位等待。", callnumber, bankQueue.GetLength(),DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"));
bankQueue.In(callnumber);
}
else
Console.WriteLine("请重试");
Console.WriteLine();
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message + ex.StackTrace);
}
}
表示一个恒定不变的字符序列集合
不能被其他类继承,直接继承自object
是引用类型
在托管堆上而不是在吸纳从的堆栈上分配空间
对串的所有操作的结果都是生成了新串而没有改变原串
public sealed class String:IComparable,ICloneable,IConvertible,IComparable<string>,IEnumerable<char>,IEnumerable,IEquatable<string>
{
public String(char[] value);
public static bool operator !=(string a, string b);
public static bool operator ==(string a, string b);
public object Clone();
public static int Compare(string strA, string strB);
public iint Compare(string strB);
public static int CompareOrdinal(string strA,string strB);
public static string Concat(string str0, string str1);
public static string Copy(string str);
public void CopyTo(iint sourceIndex,char[] destination, int destinationIndex, int count);
public bool StartsWith(string value, StringComparison comparisonType);
public bool EndsWith(string value, StriingComparison comparisonType);
public static string Format(string format,object arg0);
public int IndexOf(string value);
public string Insert(int startIndex, string value);
public string Remove(int startIndex, int count);
public string Replace(string oldVlaue,string newValue);
public string Substring(int startIndex, int length);
public string ToLower();
public string ToUpper();
public string Trim(params char[] trimChars);
}
https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/
输入: "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
public int LengthOfLongestSubstring(string s)
{
int start = 0;
int len = 0 ;
int[] str = new int[128];
for(int i = 0;i<s.Length;i++)
{
start = Math.Max(str[s[i]],start);
len = Math.Max(len,i - start +1);
str[s[i]] = i +1;
}
return len;
}
https://leetcode-cn.com/problems/substring-with-concatenation-of-all-words/
注意子串要与 words 中的单词完全匹配,中间不能有其他字符,但不需要考虑 words 中单词串联的顺序。
输入:
s = "barfoothefoobarman",
words = ["foo","bar"]
输出:[0,9]
解释:
从索引 0 和 9 开始的子串分别是 "barfoo" 和 "foobar" 。输出的顺序不重要, [9,0] 也是有效答案。
from collections import Counter
if not s or not words:return []
one_word = len(words[0])
all_len = len(words) * one_word
n = len(s)
words = Counter(words)
res = []
for i in range(0, n - all_len + 1):
tmp = s[i:i+all_len]
c_tmp = []
for j in range(0, all_len, one_word):
c_tmp.append(tmp[j:j+one_word])
if Counter(c_tmp) == words:
res.append(i)
return res
https://leetcode-cn.com/problems/replace-the-substring-for-balanced-string/
有一个只含有‘Q‘
,?‘W‘
,?‘E‘
,‘R‘
四种字符,且长度为?n
的字符串。假如在该字符串中,这四个字符都恰好出现n/4
次,那么它就是一个「平衡字符串」。
给你一个这样的字符串?s
,请通过「替换一个子串」的方式,使原字符串?s
变成一个「平衡字符串」。你可以用和「待替换子串」长度相同的任何其他字符串来完成替换。
请返回待替换子串的最小可能长度。
如果原字符串自身就是一个平衡字符串,则返回 0。
示例1:
输入:s = "QWER"
输出:0
解释:s 已经是平衡的了。
示例2:
输入:s = "QQWE"
输出:1
解释:我们需要把一个 ‘Q‘ 替换成 ‘R‘,这样得到的 "RQWE" (或 "QRWE") 是平衡的。
示例3:
输入:s = "QQQW"
输出:2
解释:我们可以把前面的 "QQ" 替换成 "ER"。
示例4:
输入:s = "QQQQ"
输出:3
解释:我们可以替换后 3 个 ‘Q‘,使 s = "QWER"。
public int BalancedString(string s) {
int n = s.Length;
int num = n/ 4 ; //平均次数
if(n < 4 || n % 4 >0)
return 0;
Dictionary<char, int> dict = new Dictionary<char, int>();
string copyS = String.Copy(s);
int l = copyS.Length;
while(copyS.Length >0)
{
char c =Convert.ToChar(copyS.Substring(0,1));
string str = copyS.Replace(c.ToString(),"");
if(l-str.Length > num)
dict.Add(c,l-str.Length-num);
l = str.Length;
}
int result = 0;
Queue<int> queue = new Queue<int>();
for(int i = 0;i<s.Length;i++)
{
if(dict.ContainsKey(s[i]))
{
dict[s[i]]--;
queue.Enqueue(i);
bool check= true;
foreach(var v in dict.Values)
{
if(v>0)
{
check = false;
break;
}
}
if(check)
{
while(queue.Count != 0)
{
int j = queue.Peek();
queue.Dequeue();
result = Math.Min(result, i - j +1);
dict[s[j]]++;
if(dict[s[j]] >0)
{
break;
}
}
}
}
}
return result;
}
标签:linked thread 单链表 time iso with ott 部分 自己
原文地址:https://www.cnblogs.com/liying-yds/p/12656275.html